【问题标题】:Convert code to constexpr将代码转换为 constexpr
【发布时间】:2016-01-21 13:52:36
【问题描述】:

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

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

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

【问题讨论】:

  • 这太笼统了。
  • @DavidHaim 哪里有这样的一般问题?我把问题移到那个地方。有类似的地方吗?
  • 您有什么东西应该(或可能)是编译时表达式或值吗?您是否有满足constexpr function 的所有要求的功能?然后你可以创建表达式、变量或函数constexpr。如果你做了一些东西 constexpr 并没有什么坏处,如果它真的不是或不能是编译时常量,它只是暗示 const 在这种情况下。
  • @JoachimPileborg 目前没有,但想要。我不使用reinterpret_cast,放置new 和其他奇怪的东西。但我想写一个constexpr 代码,从读者的角度来看,它类似于非constexpr 对应的代码。我想建立某种双射。

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


【解决方案1】:

对于标准库中的大多数算法和实用程序类(std::bitset、std::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 声明。
  • lambda 的替代方法是编写您自己的函数对象 constexpr operator()。
  • reinterpret_cast 的替代方法是使用constexpr variant(下面有一个union)。
  • goto 的替代方法是使用 常规循环和分支。

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

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

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

【讨论】:

  • 从原始存储中替代reinterpret_cast 是使用constexpr 变体(例如this)。
猜你喜欢
  • 2018-01-01
  • 1970-01-01
  • 2017-09-23
  • 2012-04-25
  • 2018-11-05
  • 2013-10-24
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多