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

3

22

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

Friede answered 7/7, 2014 at 11:50 Comment(0)
P
26

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.

Pillow answered 7/7, 2014 at 11:55 Comment(3)
Thanks for the answer, which explains the first part of the question. I roll my own code for printing vectors too. What I don't understand (second part of the question) is how we get this type of l-ref/r-ref error when an overload cannot be found.Friede
That overload is not an implementation detail, but required by the standard 27.7.1 <ostream> synopsis, to allow insertion into a temporary stream. Something like: std::ofstream("output.txt") << "Hi there\n";Apivorous
@DavidRodríguez-dribeas Thanks, amended. I only checked on cppreference quickly and didn't find it there.Pillow
A
9

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.

Avirulent answered 7/7, 2014 at 12:28 Comment(5)
While the output from the compiler might be better, the reported error makes all the sense in the context of the standard. It fails to compile and there is an overload that almost matches except for the lvalue-ness of the argument... I see that bug more like an enhancement request than a real bug.Apivorous
@DavidRodríguez-dribeas I revised my answer and changed "bug report" to "enhancement request". That was the only place saying "bug". It is very important for me to quickly identify the problem. When I first ran into this problem, it took me some time figure out what's happening; the error message put me on the wrong track. As this question shows, I am not the only one who had difficulties understanding the that error message. Well, call this issue an enhancement request or whatever you want, even the gcc developers admit that this is an issue and tried to improve it. So it is an issue.Avirulent
@DavidRodríguez-dribeas OK, I have revised the wording at several places, perhaps it was too strong. I hope you will find it OK now, thanks for drawing my attention to it.Avirulent
Don't get me wrong, I would understand (and appreciate) if the gcc developers considered this a bug. I only meant to draw a bit of attention to the fact that this is a QoI issue, not an error in how the compiler processes the program.Apivorous
@DavidRodríguez-dribeas Agreed. That's why I revised my answer. Thanks for drawing my attention to my questionable wording!Avirulent
M
-1

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;
Monetary answered 7/7, 2014 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.