2016-11-20 4 views
-3

Было несколько сообщений на эту тему, но я думаю, что это один из самых простых примеров, и, надеюсь, это прояснит некоторые вещи о cout и инициализации.не может связывать 'std :: ostream {aka std :: basic_ostream <char>}' lvalue to 'std :: basic_ostream <char> &&'

Так это работает:

class A { 
    public: 
    std::ostream& operator<< (std::ostream& os) { 
     return os; 
    } 
}; 

class B { 
    std::ostream& operator<< (std::ostream& os) { 
     A a(); //  <-- LOOK 
     std::cout << a; 
     return os; 
    } 
}; 

Но если я просто A a() к A a:

class A { 
    public: 
    std::ostream& operator<< (std::ostream& os) { 
     return os; 
    } 
}; 

class B { 
    std::ostream& operator<< (std::ostream& os) { 
     A a; //  <-- LOOK 
     std::cout << a; 
     return os; 
    } 
}; 

Он бросает:

nvcc main.cpp util.cpp -o main -lcublas -std=c++11 
In file included from main.cpp:9:0: 
cout-test.hpp: In member function ‘std::ostream& B::operator<<(std::ostream&)’: 
cout-test.hpp:21:20: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’ 
     std::cout << a; 
        ^
In file included from /usr/include/c++/4.8/iostream:39:0, 
       from main.cpp:5: 
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = A]’ 
    operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) 
    ^
make: *** [main] Error 1 

я получаю ту же ошибку, если я A a в класс:

class B { 
    A a; //  <-- LOOK 
    std::ostream& operator<< (std::ostream& os) { 
     std::cout << a; 
     return os; 
    } 
}; 

Что дает?

+0

'std :: cout << a' does *** *** не вызывает функцию' operator << 'member. И единственная причина, по которой компилируется первый код, состоит в том, что это [самый неприятный синтаксический анализ] (https://en.wikipedia.org/wiki/Most_vexing_parse). –

+0

Замечательно! Не могли бы вы объяснить, что еще немного? – ethanabrooks

ответ

1

Первый случай

A a(); 

не строит объект. Он объявляет функцию. Эта проблема синтаксического анализа известна как The Most Vexing Parse.

A a(); 
    std::cout << a; 

работает, потому что a превращается в bool в этом случае. См. Why does pointer to int convert to void* but pointer to function convert to bool?, почему это работает.

Второй случай

A a; 
    std::cout << a; 

не работает из-за того, как вы определили функцию operator<<. Вы должны будете использовать

A a; 
    a << std::cout; 

operator<< функция должна быть функцией, не являющееся членом, чтобы использовать:

A a; 
    std::cout << a; 

См my answer to another SO post, чтобы понять, почему.