将代码转换为 constexpr
Convert code to constexpr
将代码转换为constexpr
的一般技巧是什么?比如说,有一种算法可以对(输入)几何图形进行某种几何转换。输入和输出因性质和大小而异,并且彼此之间不平凡地相互依赖。目前它作为一个类实现,目前使用 std::map
和 std::vector
(不损失通用性)。
代码、使用动态内存、获取符合常量表达式要求的代码的方法是什么?
我可以想象constexpr
兼容容器和constexpr
兼容的"堆栈分配器"(用于足够大的存储)的实现的某种组合,用于使用的每个value_type
容器。但有一个问题:我从未遇到过这样的容器。但也许还有另一种方法?
对于标准库中的大多数算法和实用程序类(std::bitset
、std::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++委员会投诉。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 将INT32BE宏转换为 constexpr 是否正确?
- Boost.Hana:在 constexpr 上下文中将值元组转换为相应类型的元组
- 将 'hana::string' 转换为 'constexpr const char (&)[]'
- constexpr 链表 - 从 const X* 到 X* 的转换无效
- 转换运算符,它引用类模板参数和 constexpr 类成员
- 将 constexpr 结构转换为运行时结构
- 为什么 constexpr 隐式转换并不总是有效?
- 指向数据成员转换的 Constexpr 指针
- 在 C++11 中将静态 constexpr 数组转换为模板参数
- 将结构转换为 constexpr 数组uint8_t
- 子类ConstexPR类以获得不同的用户定义的转换行为
- 我可以将C 17 Capture lambda ConstexPR转换操作符的结果用作函数指针模板非类型参数吗?
- 将variadic模板转换为constexpr
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 编译时类型转换检查(constexpr和用户定义的文字)
- 如何将模板大小的数组初始化转换为 constexpr 初始化
- 通过显式转换函数初始化枚举类类型的静态constexpr类成员
- 十六进制字符到std::string的Constexpr转换