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

35,992

Solution 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.

Solution 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.

Share:
35,992

Related videos on Youtube

thor
Author by

thor

Updated on August 15, 2022

Comments

  • thor
    thor over 1 year

    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

  • thor
    thor almost 10 years
    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.
  • David Rodríguez - dribeas
    David Rodríguez - dribeas almost 10 years
    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";
  • David Rodríguez - dribeas
    David Rodríguez - dribeas almost 10 years
    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.
  • Ali
    Ali almost 10 years
    @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.
  • Ali
    Ali almost 10 years
    @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.
  • Angew is no longer proud of SO
    Angew is no longer proud of SO almost 10 years
    @DavidRodríguez-dribeas Thanks, amended. I only checked on cppreference quickly and didn't find it there.
  • David Rodríguez - dribeas
    David Rodríguez - dribeas almost 10 years
    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.
  • Ali
    Ali almost 10 years
    @DavidRodríguez-dribeas Agreed. That's why I revised my answer. Thanks for drawing my attention to my questionable wording!