10

N2976建议constexpr在标准库中添加一些位置。它指出iostreams 不适用于constexprEXCEPT 结束迭代器。所以istream_iterator并被istreambuf_iterator赋予了constexpr默认构造函数,仅此而已。例如,您可以在整个文件中只出现一次的libstdc++ 实现中看到。constexpr引发此更改的 LWG 是#1129。它说:

istream_iterator并且istreambuf_iterator应该支持文字标记值。默认构造函数经常用于终止范围,并且很容易成为 的字面值 istreambuf_iterator,以及istream_iterator迭代值类型时。[其余省略]

这对我来说没有多大意义。有人可以给我举个例子来说明他们的意思吗?

N3308是另一篇提到但未解释该问题的论文:

某些istream_iterator<T>构造函数必须是 constexprifT是文字类型。目的是允许存储一种T内联类型的现有实现技术继续工作。[libstdc++ 这样做,_Tp _M_value] 但是,它实际上排除了这种技术:T不需要标记的默认和复制构造函数constexpr,如果没有,则 istream_iterator<T>构造函数不能被实例化为 constexpr

上面解释了琐碎的复制构造函数和析构函数,但没有解释为什么默认构造函数被标记为 constexpr。

此外,在在线 GCC 5.2.0 上进行测试时,我复制了 libstdc++ 的实现。唯一的变化是我从istream_iterator(). 在这两种情况下,组件都是相同的。

用 constexpr

没有 constexpr

4

1 回答 1

3

流迭代器的结尾用作标记值的示例如下:

// istream_iterator example
#include <iostream>     // std::cin, std::cout
#include <iterator>     // std::istream_iterator

int main () {
  double value1, value2;
  std::cout << "Please, insert two values: ";

  std::istream_iterator<double> eos;              // end-of-stream iterator
  std::istream_iterator<double> iit (std::cin);   // stdin iterator

  if (iit!=eos) value1=*iit;

  ++iit;
  if (iit!=eos) value2=*iit;

  std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n';

  return 0;
}

http://www.cplusplus.com/reference/iterator/istream_iterator/istream_iterator/

声明这个 aconstexpr允许编译器将创建流结束迭代器的调用折叠成常量,而不是每次都调用一个函数。否则它可能不得不在循环的每次迭代中这样做。

于 2015-09-19T08:20:47.723 回答