为什么流仍然转换为C ++ 11中的指针?

时间:2013-02-02 03:28:11

标签: c++ c++11 g++ std iostream

从文本文件中读取行的规范方法是:

std::fstream fs("/tmp/myfile.txt");
std::string line;
while (std::getline(line, fs)) {
   doThingsWith(line);
}

(不,it is not while (!fs.eof()) { getline(line, fs); doThingsWith(line); }!)

这有效,因为std::getline通过引用返回stream参数,因为:

  • 在C ++ 03中,流通过void*中的operator void*() const转换为std::basic_ios,在设置fail错误标志时评估为空指针值;
    • [C++03: 27.4.4]& [C++03: 27.4.4.3/1]
  • 在C ++ 11中,流通过bool中的explicit operator bool() const转换为std::basic_ios,当设置false错误标志时评估为fail
    • [C++11: 27.5.5.1]& [C++11: 27.5.5.4/1]

在C ++ 03中,这种机制意味着以下几种可能:

std::cout << std::cout;

它正确地导致一些任意指针值输出到标准输出流。

然而,尽管在C ++ 11中删除了operator void*() const,但它也在C ++ 11模式的GCC 4.7.0中编译并运行。

在C ++ 11中这仍然有可能吗?是否还有其他一些我不知道的工作机制?或者它只是一个实现“古怪”?

3 个答案:

答案 0 :(得分:6)

到GCC 4.6.2为止,the libstdc++ code for basic_ios显然仍然像C ++ 03一样。

我只是简单地说“他们还没有接触到它”。

相比之下,the libc++ (LLVM's stdlib implementation) trunk已使用operator bool()

答案 1 :(得分:6)

我有理由相信在C ++ 11的一致性实现中不允许/不会发生这种情况。

问题当然是,现在,大多数实现都在努力进行整合,但还没有完全实现。对于许多供应商来说,这个特定的更新是一个相当低的优先级。它改进了错误检查,但很少(或没有)启用新技术,添加新功能,提高运行时效率等。这使编译器能够捕获您引用的错误(some_stream << some_other_stream)但不会否则,确实会产生很大的不同。

如果我负责更新C ++ 11的标准库,我认为这将是相当低优先级。还有其他一些变化可能很容易(如果不是更容易)合并,并且可能会给大多数程序员带来更大的差异。

要使用您提供的示例之一,如果我负责更新VC ++标准库以利用11月CTP中添加的编译器功能,那么我的首要任务可能是将构造函数添加到标准容器类型接受initialization_list。这些相当容易添加(我猜一个人可能会在一周内添加并测试它们)并且在程序员可以做的事情上做出明显的,明显的区别。

答案 2 :(得分:2)

这是一个错过的迷你功能,埋在一个预先存在的标题中。在2011年之前的组件中可能存在许多遗漏和佣金错误。

真的,如果有人在gcc中提出这样的事情,那么去Bugzilla并制作错误报告会有一个好的世界。它可能是一个低优先级的错误,但如果你开始纸上谈兵

我会把这个想法扩展到所有其他C ++编译器:clangVisual Studio等。

这将使C ++变得更好。

P.S。我输入了bug in Bugzilla