constexpr结束istream(sentinel)迭代器有什么意义?

时间:2015-09-19 07:54:11

标签: c++ c++11 constexpr istream-iterator

N2976建议将constexpr添加到标准库中的某些位置。它指出iostream不适合constexpr除了结束迭代器。因此,istream_iteratoristreambuf_iterator被赋予constexpr默认构造函数,这就是它。例如,您可以在libstdc++ implementation中看到constexpr仅在整个文件中出现一次。引发这一变化的LWG是#1129。它说:

  

istream_iteratoristreambuf_iterator应支持文字   哨兵价值观。默认构造函数经常用于   终止范围,并且很容易成为字面值   迭代值时istreambuf_iteratoristream_iterator   类型。 [其余省略]

这对我来说并没有多大意义。有人能告诉我他们的意思吗?

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

  

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

上面解释了普通的复制构造函数和析构函数,但不是默认构造函数标记为constexpr的原因。

此外,在在线GCC 5.2.0上进行测试,我复制了libstdc ++的实现。唯一的变化是我从node *InitQueue(node * head) { node *temp; temp = (node *) malloc(sizeof(node)); printf("%p \n", temp); temp->next = temp; head = temp; printf("%p \n", head->next); return head; } 删除了constexpr。在这两种情况下,组件都是相同的。

With constexpr

Without constexpr

1 个答案:

答案 0 :(得分: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/

声明这个constexpr允许编译器将创建end-of-stream迭代器的调用折叠成常量,而不是每次都调用一个函数。否则它可能必须在循环的每次迭代中这样做。