constexpr end istream(哨兵)迭代器的意义何在?

What's the point of constexpr end istream (sentinel) iterators?

本文关键字:迭代器 istream end 哨兵 constexpr      更新时间:2023-10-16

N2976建议在标准库中的一些点中添加constexpr。它注意到,除了结束迭代器之外,iostream不适合constexpr。因此,istream_iteratoristreambuf_iterator被赋予了constexpr默认构造函数,仅此而已。例如,您可以在libstdc++实现中看到,constexpr在整个文件中只出现一次。引发这一变化的LWG是#1129。上面写着:

istream_iteratoristreambuf_iterator应支持文字sentinel值。默认构造函数经常用于终止范围,并且可以很容易地成为CCD_ 10和CCD_类型。[省略其余部分]

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

N3308是另一篇提到但没有解释这个问题的论文:

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

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

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

带constexpr

无constexpr

流结束迭代器用作sentinel值的示例如下:

// 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允许编译器将创建流结束迭代器的调用合并为常量,而不是每次调用一个函数。否则,它可能必须在循环的每次迭代中都这样做。