C ++ 11:二进制表达式ostream和ostringstream的操作数无效

时间:2013-08-26 16:38:31

标签: c++11

为什么以下不再是有效的C ++ 11代码(编译好像C ++ 98一样):

#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os;
  os << "Hello World!";
  std::cout << os << std::endl;
  return 0;
}

这里的参考是(截断)我得到的clang:

$ clang++ -stdlib=libc++ -std=c++11 t.cxx
t.cxx:8:13: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::ostringstream' (aka 'basic_ostringstream<char>'))
  std::cout << os << std::endl;
  ~~~~~~~~~ ^  ~~
/usr/include/c++/v1/ostream:190:20: note: candidate function not viable: no known conversion from 'std::ostringstream' (aka 'basic_ostringstream<char>') to
      'const void *' for 1st argument; take the address of the argument with &
    basic_ostream& operator<<(const void* __p);

2 个答案:

答案 0 :(得分:13)

它可以在C ++ 03中编译,但它没有一点意义。 C ++ 11刚刚使用了一个新功能来使代码毫无意义,而不是首先编译。

请参阅std :: ostringstream(和所有其他流类),用于隐式转换为void*。然而,这返回的不是一个正确的指针;如果流处于无效状态,则它只是null,如果有效则不为null。这就是允许你写的东西。

std::ofstream ofs("filename");
if (ofs) ...

然而,转换为void *是有问题的,因为你做了其他带有void *的愚蠢的东西。甚至在C ++ 11之前,发现了更好的安全布尔习语。但是对于C ++ 11,添加了显式转换,这些转换要好得多。因此对于C ++ 11,转换为void*被显式转换为bool所取代,这允许编译相同的有用代码而不允许编译无用的代码(例如你的代码)。这就是为什么代码在C ++ 11中不再起作用的原因。

这不是一件坏事。那是一件好事。你发现你所拥有的代码没有意义,没有它在运行时行为不端的痛苦。

答案 1 :(得分:3)

执行您打算执行的操作的代码如下:

#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os;
  os << "Hello World!";
  std::cout << os.str() << std::endl;
  return 0;
}