9

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

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

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

这是有效的,因为std::getline通过引用返回流参数,并且因为:

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

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

std::cout << std::cout;

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

但是,尽管operator void*() const已在 C++11 中删除,但它也可以在 C++11 模式下的 GCC 4.7.0 中为我编译和运行。

这在 C++11 中怎么可能?还有其他一些我不知道的机制在起作用吗?或者它只是一个实现“奇怪”?

4

3 回答 3

6

直到 GCC 4.6.2,libstdc++ 的代码basic_ios显然仍然类似于 C++03。

我只是把它归结为“他们还没有解决这个问题”。

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

于 2013-02-02T03:30:57.250 回答
6

我有理由确定这在符合 C++11 的实现中是不允许/不能发生的。

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

如果我负责更新 C++11 的标准库,我认为这将是一个相当低的优先级。还有其他一些更改可能同样容易(如果不是更容易)合并,并且可能对大多数程序员产生更大的影响。

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

于 2013-02-02T04:30:03.140 回答
2

这是一个隐藏在预先存在的标题中的错过的迷你功能。2011 年之前的组件中可能存在大量遗漏和委托错误。

真的,如果有人在 gcc 中想出了这样的事情,那么去Bugzilla并提交错误报告会大有裨益。这可能是一个低优先级的错误,但如果您开始书面记录

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

这将使 C++ 成为一个更好的地方。

PS 我在 Bugzilla 中输入了一个错误

于 2013-02-03T15:55:33.330 回答