std :: vector:无法绑定&#39; std :: ostream {aka std :: basic_ostream <char>}&#39;左值&#39; std :: basic_ostream <char>&amp;&amp;&#39; </char> </char>

时间:2014-07-07 11:50:11

标签: c++ gcc c++11 stl iostream

尝试执行像

这样简单的操作时遇到了令人困惑的错误消息
std::cout << std::vector<int>{1,2,3};

 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}; }

(使用gcc-4.8.1和-std = c ++ 11测试)

SO有类似的问题,如Overloading operator<<: cannot bind lvalue to ‘std::basic_ostream<char>&&’,这是关于一些带嵌套类的用户定义类。还有一个工作围绕这个问题的公认答案。

但我不知道这是否适用于std::vector。有人可以解释为什么std::vector发生了这个错误,以及如何解释它?

由于

3 个答案:

答案 0 :(得分:21)

模板相关的错误消息有时会让人感到困惑。问题是标准库没有定义operator <<的重载,用于将std::vector(或任何其他容器)插入std::ostream。因此编译器无法为operator <<找到合适的重载,并且尽可能地报告此失败(遗憾的是,在您的情况下不太好/可读)。

如果要流式传输整个容器,可以使用std::ostream_iterator

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

至于为什么你正好得到这个神秘的错误,它有助于分析完整的错误信息:

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)
     ^

显然有operator<<的模板重载,它接受类型为std::ostream&&的lhs参数和模板化类型的rhs参数;它存在以允许插入临时流。由于它是一个模板,因此它成为代码中表达式的最佳匹配。但是,std::cout是左值,因此无法绑定到std::ostream&&。因此错误。

答案 1 :(得分:9)

这是gcc的一个已知问题,I filed an enhancement request regarding this.

“唯一”问题是您尝试打印到控制台的内容没有operator<<。不幸的是,错误消息不是很有帮助。 :(

顺便说一句,这个问题与vector或l值和r值引用无关。一个最小的例子:

#include <iostream>

struct A { };

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

请参阅增强请求中有关血淋淋的详细信息的讨论。简而言之,gcc开发人员已经尝试改进错误消息,但事实证明这是非常困难的。

对于它的价值,使用libc ++的clang's error message在我看来更清晰

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;
    ~~~~~~~~~ ^  ~

在这里,第一行清楚地说明了问题所在。

答案 2 :(得分:-1)

课程operator <<中的课程std::vector没有定义std::basic_ostream

您想要的是以下

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

虽然可以写得更简单

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