5

为什么以下不再是有效的 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);
4

2 回答 2

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 中不再工作的原因。

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

于 2013-08-26T16:41:41.580 回答
3

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

#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os;
  os << "Hello World!";
  std::cout << os.str() << std::endl;
  return 0;
}
于 2013-08-26T18:47:17.923 回答