【发布时间】:2015-09-19 07:54:10
【问题描述】:
N2976 建议将constexpr 添加到标准库中的某些位置。它指出 iostreams 不适用于 constexpr 除了结束迭代器。所以istream_iterator 和istreambuf_iterator 被赋予constexpr 默认构造函数,仅此而已。例如,您可以在libstdc++ implementation 中看到constexpr 在整个文件中只出现一次。引发此更改的 LWG 是 #1129。它说:
istream_iterator和istreambuf_iterator应该支持字面量 哨兵价值观。默认构造函数经常用于 终止范围,并且很容易成为istreambuf_iterator和istream_iterator迭代值时 类型。 [其余省略]
这对我来说没有多大意义。谁能给我举个例子来说明他们的意思吗?
N3308 是另一篇提到但未解释该问题的论文:
一些
istream_iterator<T>构造函数必须是constexpr如果T是文字类型。目的是让 现有的将T类型内联存储到的实现技术 继续工作。 [libstdc++ 这样做,_Tp _M_value] 但是,它 实际上排除了这种技术:默认和复制构造函数 的T不需要标记constexpr,如果不是,则istream_iterator<T>构造函数无法实例化为constexpr.
上面解释了琐碎的复制构造函数和析构函数,但没有解释为什么默认构造函数被标记为 constexpr。
此外,在在线 GCC 5.2.0 上进行测试时,我复制了 libstdc++ 的实现。唯一的变化是我从istream_iterator() 中删除了 constexpr。在这两种情况下,组件都是相同的。
【问题讨论】:
-
什么不清楚?默认构造的流迭代器通常用作结束迭代器,例如
while (iter != istream_iterator())。将其作为constexpr可能会在循环中为我们节省一两纳秒。 -
@BoPersson 如果只有结束迭代器可以是
constexpr,表达式constexpr怎么样? (另外我不相信“为我们节省一两纳秒”可以证明一个缺陷,一篇论文,然后图书馆实施者认为它值得开发时间) -
我认为“移动”迭代器需要调用实时数据,因此无法在编译时确定其状态。但是 terminating 迭代器可以是完全静态的,并且可以在编译时完全推导出来,因为它所要做的就是将 equal 与耗尽数据的“移动”迭代器进行比较。
-
表达式不是
constexpr(无论如何这也不能用作循环条件),但是将iter与一个常数进行比较可能比与其他的比较便宜。 -
@BoPersson 不是
constexpr允许在静态初始化阶段进行常量初始化吗? non-static-storage-duration 临时本地对象可以静态初始化吗?
标签: c++ c++11 constexpr istream-iterator