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

Lig*_*ica 9 c++ iostream g++ std c++11

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

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

(不,不是 while (!fs.eof()) { getline(line, fs); doThingsWith(line); }!)

这项工作beacuse std::getline通过引用返回stream参数,因为:

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

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

std::cout << std::cout;
Run Code Online (Sandbox Code Playgroud)

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

但是,尽管operator void*() const已经在C++ 11中删除了,但它也可以在G ++ 4.7.0中以C++ 11模式编译并运行.

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

Lig*_*ica 6

直到GCC 4.6.2,libstdc ++代码basic_ios显然仍然像C++ 03一样.

我只是简单地说"他们还没有到处".

相比之下,libc ++(LLVM的stdlib实现)主干已经使用了operator bool().

  • 还有一个关于此的投票!这是怎么回事?这个答案有什么问题,祈祷告诉?我知道它回答了这个问题,因为我写了这个问题. (4认同)
  • 它也可以是为了向后兼容目的而包含的"特定于实现的非便携式扩展". (3认同)
  • 好吧,我会尝试解决它.;)它不会成为4.8,因为它即将分支.我怀疑在2011年之前的旧标题中有很多缺失的位.我们都非常想加入新的东西. (3认同)

Jer*_*fin 6

我有理由相信这是不允许的/不可能在C++ 11的一致性实现中发生.

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

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

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

  • +1:libc ++给出:错误:二进制表达式的操作数无效. (2认同)