将代码转换为 constexpr

Convert code to constexpr

本文关键字:constexpr 转换 代码      更新时间:2023-10-16

将代码转换为constexpr的一般技巧是什么?比如说,有一种算法可以对(输入)几何图形进行某种几何转换。输入和输出因性质和大小而异,并且彼此之间不平凡地相互依赖。目前它作为一个类实现,目前使用 std::mapstd::vector(不损失通用性)。

重构

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

我可以想象constexpr兼容容器和constexpr兼容的"堆栈分配器"(用于足够大的存储)的实现的某种组合,用于使用的每个value_type容器。但有一个问题:我从未遇到过这样的容器。但也许还有另一种方法?

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

通常会阻止此类代码编译的是当前对编译时常量表达式的语言限制之一,例如(查看 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变体(下面有一个union)。
  • goto的替代方法是使用常规循环和分支。

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

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

如果您

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