std::vector : cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

大兔子大兔子 提交于 2019-11-27 21:14:44

问题


I encountered a confusing error message when trying to do something as simple as

std::cout << std::vector<int>{1,2,3};

which says

 cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
 int main() {  std::cout << std::vector<int>{1,2,3}; }

(tested using gcc-4.8.1 with -std=c++11)

SO has similar questions like Overloading operator<<: cannot bind lvalue to ‘std::basic_ostream<char>&&’, which is about some user defined class with nested classes. There is also a work around the accepted answer to that question.

But I don't know whether this applies to std::vector. Can someone explain why this error happens to std::vector, and how to interpret it?

Thanks


回答1:


Template-related error messages can be confusing at times. The problem is that the standard library does not define an overload of operator << for inserting std::vector (or any other container, for that matter) into a std::ostream. So the compiler fails to find a suitable overload for operator <<, and reports this failure as best as it's able (which is unfortunately not too good/readable in your case).

If you want to stream an entire container, you can use std::ostream_iterator for that:

auto v = std::vector<int>{1, 2, 3};
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));

As for why you're getting precisely this cryptic error, it helps to analyse the full error message:

prog.cpp: In function ‘int main()’:
prog.cpp:13:37: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
  std::cout << std::vector<int>{1,2,3};
                                     ^
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from prog.cpp:3:
/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 = std::vector<int>]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

There is apparently a template overload of operator<< which takes a lhs argument of type std::ostream&& and a rhs argument of the templated type; it exists to allow insertion into temporary streams. Since it's a template, it becomes the best match for the expression in your code. However, std::cout is an lvalue, so it cannot bind to std::ostream&&. Hence the error.




回答2:


This a known issue with gcc, I filed an enhancement request regarding this.

The "only" problem is that the thing you are trying to print out to the console has no operator<<. Unfortunately, the error message is not very helpful. :(

By the way, the question has nothing to do with vector or l-value and r-value references. A minimal example:

#include <iostream>

struct A { };

int main() {
    A a;
    std::cout << a;
}

See the discussion at the enhancement request for the gory details. In short, the gcc developers had already tried to improve the error message but it proved to be notoriously difficult.

For what it is worth, clang's error message with libc++ is clearer in my opinion:

clang++ -std=c++11 -stdlib=libc++ -lc++abi main.cpp && ./a.out
main.cpp:7:15: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A')
    std::cout << a;
    ~~~~~~~~~ ^  ~

Here, the first line clearly says what the problem is.




回答3:


There is no defined operator << for class std::vector in class std::basic_ostream.

What you want is the following

for ( int x  : std::vector<int> { 1, 2, 3 } ) std::cout << x << ' ';
std::cout <<  std::endl;

Though it can be written simpler

for ( int x  : { 1, 2, 3 } ) std::cout << x << ' ';
std::cout <<  std::endl;


来源:https://stackoverflow.com/questions/24609915/stdvector-cannot-bind-stdostream-aka-stdbasic-ostreamchar-lvalue-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!