C++14标准库的哪些部分可以或将会被转换为constexpr?

32
随着新的放松的C++14常量表达式规则,编译时编程变得更加具有表现力。我想知道标准库是否也会升级以利用这一点。特别是,std::initializer_liststd::pairstd::tuplestd::complexstd::bitsetstd::array似乎是被标记为constexpr的主要候选项。

问题:

  • 哪些部分的标准库会被标记为constexpr
  • 哪些其他部分可以被标记为constexpr
  • 例如,为什么<cmath><algorithm>中的函数没有被标记为constexpr
  • 是否存在向后兼容性原因不这样做?

2
如果你感到好奇,你可能想要看一下libc++,C++14的constexpr化工作正在进行中。 - Matthieu M.
@MatthieuM。谢谢,SVN主干确实有几个// constexpr in C++14的注释。 - TemplateRex
2个回答

26

哪些标准库的部分现在将被标记为constexpr?

根据我查看的C++14草案N3690,目前以下内容将与C++11标准相比更改为constexpr

  • std::error_category 的默认构造函数
  • std::forward
  • std::move
  • std::move_if_noexcept
  • 所有的 std::pair 运算符比较
  • std::pairstd::tuplestd::get
  • std::make_tuple
  • 所有的 std::tuple 运算符比较
  • 所有的 std::optional 运算符比较
  • 所有的 std::optional 构造函数(除了移动)
  • std::bitset 和其他容器的 operator[]size
  • 所有的 std::complex 运算符比较

由于是手动翻译,可能存在一些错误 :(

对于可能更正确的constexpr添加列表,您可以查看:N3469, N3470N3471

哪些其他部分可以标记为constexpr?

大部分可用constexpr(如std::numeric_limits的评估、std::tuplestd::pair构造函数等)已在C++11标准中标记为constexpr。存在一个问题,即std::ratio的时间点和其他组件未被标记为constexpr,但在N3469中已修复。

有益于加入constexpr的内容是std::initializer_list,但它并未在此次更新中得到改进(我不确定是否有任何建议允许改进)。

是否存在向后兼容性原因而不能这样做?

由于这是一个扩展,大多数东西不会被破坏,因为旧代码仍将按原样编译,现在也没有非法形式。然而,如果您没有预料到的话,将constexpr添加到旧事物中可能会导致一些令人惊讶的结果,例如在此提供的示例(感谢TemplateRex)。


+1,谢谢,非常好的概述。然而我想知道:a) 为什么 std::array<T,N> 不是完全 constexpr,b) 例如 std::complex 的修改成员函数 (operator*= 等) 为什么没有标记为 constexpr。正如这个问答所示,Clang 已经实现了这样的行为。同样,使整个 <cmath><algorithm> 头文件都 constexpr 的障碍是什么?我希望能够在编译时对数组进行排序。 - TemplateRex
让我们也注意到,constexpr 中可以包含的规则相当宽松。检查 Clang 的测试用例时,我注意到例如 for 循环等内容。 - Matthieu M.
@MatthieuM。是的,非常放松,所以我认为当前的N3690草案相对于可以完成的事情而言相当严格。理想情况下,我真的希望例如std::complex和其他值类完全成为constexpr - TemplateRex
顺便提一下,可能存在向后兼容性问题,请参见例如Clang邮件列表上的此线程 - TemplateRex
@TemplateRex 将东西添加为 constexpr 可能会导致破坏性变化,你可能是正确的。 - Rapptz

4
上周(2013年9月23日至28日),标准委员会在标准库中的更多例程中添加了“constexpr”。
  • forward_as_tuple
  • 所有比较/逻辑/位命名运算符的operator()方法。(less,greater,plus,minus,bitwise_and,logical_or,not1等)
@TemplateRex:我们越来越接近在编译时对数组进行排序。
然而,我们还解决了LWG 2013问题,指出标准库实现者不能将未在标准中定义为“constexpr”的调用作为“constexpr”调用,因为这种差异可能会改变某些代码的行为。

谢谢更新!关于std::reverse_iterator(有一个DR),还有我提交了一个关于std::tie的DR,类似于std::forward_tuple。在C++14最终确定之前,它们有没有可能被设置为constexpr?+1 - TemplateRex
顺便问一下,您可以(尽管主观)提及委员会对C++17中更自由的constexpr的支持吗?例如,关于constexpr lambda的NB评论听起来非常有前途。我编写了自己的std::bitset实现,除了IO和字符串转换之外,它是“constexpr”批发的。我认为库留下了更多的机会,如果语言允许的话,可以利用这些机会。您能否评论为什么没有提出这些机会?C++17提议这样广泛的库扩展是否会受到好评? - TemplateRex
我无法说为什么没有提出额外的位; 只是没有提出增补的论文。函数对象和forward_as_tuple之所以被添加,是因为我撰写了一篇论文并提出了问题。 - Marshall Clow
1
我认为库在constexpr方面有更多的机会,是的。 - Marshall Clow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接