c++ 有没有一种方法可以检测可以标记为“constexpr”的函数?

r1zhe5dt  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(122)

鉴于我想改进我的C代码库。第一步是将函数标记为constexpr,以满足所使用的C标准的要求。是否有方法确定函数是否可以标记为constexpr
我想到的唯一方法是将constexpr添加到单个示例中,运行编译器,并检查它是否抱怨它不是constexpr。重复直到检查完所有示例。这种方法无法扩展。
标签:Should we use constexpr everywhere we can?

fhity93d

fhity93d1#

在C++23中,constexpr函数有两个要求:

  • 它不是协程;
  • 如果它是构造函数或析构函数,则它的类没有虚基类。

如果你的代码库中的每个函数都满足这一点,我不会感到惊讶。
所以你可以标记每个模板化的内联函数constexpr。因为constexpr函数是隐式的inline,所以你不能对extern函数这样做。
这意味着头文件中的每个函数定义都可以是constexpr
(If你有constexpr函数的编译器错误,它永远不会产生常量表达式,升级你的编译器)

uxhixvfz

uxhixvfz2#

随着constexpr的放松越来越多,更容易问:
有没有一种方法可以检测到 * 不应该 * 是constexpr的函数?
以下函数不应该是constexpr

  • 声明/定义在头/源之间分离的函数
  • 从技术上讲,您可以将它们设置为constexpr,但如果没有定义,它们在常量表达式中将不可用
  • 没有constexpr构造函数的类的成员函数
  • 从技术上讲,它们可以是constexpr,但这个constexpr会产生误导
  • 从不产生常量表达式的函数(由于throwgoto等)
  • 从C++23开始,即使是那些也可以标记为constexpr,参见P2448: Relaxing some constexpr restrictions
  • 即使在C++23中也不适合constexpr的函数:
  • 协程
  • 具有虚拟基类的类的构造函数和析构函数

所有其他函数(在某些代码库中构成了绝大多数函数)都可以是constexpr。您甚至可以使用类似clang-tidy规则的东西来自动执行此过程。

C++20注意事项

它在C++20和更老的标准中更复杂,因为有以下规则:
对于既不是默认值也不是模板的constexpr函数或constexpr构造函数,如果不存在参数值,使得函数或构造函数的调用可能是核心常量表达式的求值子表达式,或者对于构造函数,是某些常量初始化对象的初始化全表达式的求值子表达式,则程序格式不正确,不需要诊断

  • C20 [dcl.constexpr] p6
    这个规则在前面提到的建议中被删除了,但是在C
    20中,它使得决定何时应用constexpr变得更加困难。自动证明是否存在一组参数来产生常量表达式并不容易。

相关问题