将代码转换为 constexpr

Convert code to constexpr

将代码转换为 constexpr 的一般提示是什么?比如说,有一种算法可以对(输入)几何图形进行一些几何变换。输入和输出的性质和大小各不相同,并且彼此之间存在非平凡的依赖关系。目前它实现为 class,目前使用 std::mapstd::vector(不失一般性)。

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

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

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

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

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

对于每个限制,都有办法绕过它

  • 替代系统支持的动态内存分配 通过new/delete就是自己写一个大内存池 全局 constexpr 数组。
  • 虚函数的替代方法是存储一个函数数组 指针(调用 constexpr 函数)并通过 switch 语句。
  • lambda 的替代方法是编写您自己的函数对象 constexpr operator().
  • reinterpret_cast 的替代方法是使用 constexpr variant(下面有一个 union)。
  • goto 的替代方法是编写更结构化的代码,使用 常规循环和分支。

在所有情况下,您将失去能够调用 new/delete 或隐式动态调度的语法细节。您将不得不手动 allocate/deallocate 您的内存并手动 select 您的函数指针。

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

如果您认为应该有更多或更容易的 constexpr 支持(在语言和标准库中),请向您的供应商或 C++ 委员会投诉。