使用 consteval 代替 constexpr 函数有哪些优点?

2024-01-01

我知道需求的差异,我最感兴趣的是它带来的代码质量带来的好处。

我能想到的几件事:

  • 读者只需阅读函数签名即可知道该函数是在编译时评估的
  • 编译器可能会发出更少的代码,因为constevalfns 在运行时从不使用(这是推测,我没有这方面的真实数据)
  • 不需要有变量来强制ctfe https://en.wikipedia.org/wiki/Compile_time_function_execution, 例子在最后

注意:如果代码质量太模糊,我理解有些人可能想结束这个问题,对我来说代码质量并不是那么模糊的术语,但是......

example https://www.godbolt.org/z/347Exs where constexpr失败被延迟到运行时:

constexpr int div_cx(int a, int b)
{ 
  assert(b!=0);
  return a/b;
}
    
int main()
{
    static constexpr int result = div_cx(5,0); // compile time error, div by 0
    std::cout << result; 
    std::cout << div_cx(5,0) ; // runtime error :( 
}

为了进行有意义的、显着的静态反射(编译时反射),您需要一种在编译时执行代码的方法。最初的静态反射 TS 提案使用了传统的模板元编程技术,因为这些是在编译时执行代码的唯一有效工具。

然而,作为constexpr代码获得了更多功能,通过以下方式进行编译时静态反射变得越来越可行constexpr功能。这种想法的一个问题是不能允许静态反射值泄漏到非编译时代码中。

我们需要能够编写必须only在编译时执行。对于函数中间的一小段代码来说,这样做很容易;该代码的运行时版本根本不包含反射部分,只包含它们的结果。

但是,如果您想编写一个接受反射值并返回反射值的函数怎么办?或者反射值列表?

该功能不能constexpr,因为一个constexpr功能must能够在运行时执行。你可以做一些事情,比如获取指向的指针constexpr函数并以编译器无法跟踪的方式调用它们,从而强制它在运行时执行。

采用反射值的函数无法做到这一点。它必须仅在编译时执行。所以constexpr不适合此类功能。

Enter consteval:一个函数是“必需”仅在编译时执行 https://stackoverflow.com/questions/58466245/is-compiler-allowed-to-call-an-immediate-consteval-function-during-runtime/58467438#58467438。有一些特定的规则使得指向此类函数的指针不可能泄漏到运行时代码等中。

像这样,consteval目前没有太多目的。它被用于有几个地方像source_location::current(), https://en.cppreference.com/w/cpp/utility/source_location/current这对于在运行时执行根本没有意义。但最终,该功能是尚不存在的进一步编译时编程工具的必要构建块。

这是在最初提出此功能的论文 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1073r0.html:

然而,本文的推动力是 SG7 在编译时反射领域所做的工作。现在普遍认为未来的反射语言支持应该使用constexpr函数,但由于“反射函数”通常必须在编译时求值,因此它们实际上可能是立即函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 consteval 代替 constexpr 函数有哪些优点? 的相关文章

随机推荐