将代码转换为constexpr

时间:2016-01-21 13:52:36

标签: c++ c++11 containers c++14 constexpr

将代码转换为constexpr的一般提示是什么?比方说,有一种算法可以对(输入)几何图形进行几何变换。输入和输出因性质和大小而不同,并且非常简单地相互依赖。目前它是作为一个类实现的,目前使用std::mapstd::vector(不失一般性)。

有什么方法可以重构使用动态内存的代码来获取符合常量表达式要求的代码?

我可以想象constexpr兼容容器和constexpr的某种组合 - "stack allocator"的兼容实现(对于足够大的存储空间),用于所使用的每个value_type容器。但是有一个问题:我从未遇到过这样的容器。但也许还有其他方法吗?

1 个答案:

答案 0 :(得分:5)

对于标准库中的大多数算法和实用程序类(std::bitsetstd::array等),您只需在任何地方添加constexpr说明符,尝试将结果存储在constexpr变量中。 最有可能的是,这将成功编译并运行。另请参阅this Q&A

通常会阻止此类代码编译的是编译时常量表达式的当前语言限制之一,例如(查看完整列表的 5.20常量表达式[expr.const]

  • 动态内存分配(内部std::inplace_merge例如。)
  • 虚拟函数(<iostream>
  • lambda表达式(建议并接受N4487中的标准化)
  • reinterpret_cast
  • goto(建议但在N4472标准化中被拒绝)

对于每个限制,都有办法解决它

  • 系统支持动态内存分配的替代方案 通过new / delete来编写一个大的内存池 全局constexpr数组。
  • 虚函数的替代方法是存储函数数组 指针(调用constexpr函数)并调度它们 switch声明。
  • lambdas的替代方法是用自己编写自己的函数对象 constexpr operator()
  • reinterpret_cast的替代方法是使用constexpr variant(其下方有union)。
  • goto的替代方法是使用编写更多结构化代码 常规循环和分支。

在所有情况下,您将失去能够调用new / delete或隐式动态调度的语法细节。您必须手动分配/取消分配内存并手动选择功能指针。

请注意,即使使用当前的C ++ 14/17语言,标准库的大部分也可以constexpr,但它们目前不是。此外,标准库实现者不得添加额外的constexpr功能(与允许提供更强noexcept支持相反)。

如果您认为应该提供更多或更简单的constexpr支持(包括语言和标准库),请向您的供应商或C ++委员会投诉。