使用consteval而不是conexpr函数有什么好处?

2022-05-16 00:00:00 c++ consteval c++20 constexpr

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

我能想到的几件事:

  • 读者只需阅读函数签名即可知道该函数是在编译时计算的
  • 编译器可能会发出较少的代码,因为constevalFN从不在运行时使用(这只是推测,我没有这方面的真实数据)
  • 不需要有变量来强制ctfe,最后的示例

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

example其中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函数进行编译时静态反射变得越来越可行。这种想法的一个问题是,不能允许静态反射值泄漏到非编译时代码中。

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

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

constexpr函数不能为constexpr,因为constexpr函数必须能够在运行时执行。您可以执行如下操作:获取指向constexpr函数的指针,并以编译器无法跟踪的方式调用它们,从而强制其在运行时执行。

接受反射值的函数不能做到这一点。它只能在编译时执行。因此constexpr不适用于此类功能。

Enterconsteval:"required" to execute only at compile time的函数。存在特定的规则,使得指向此类函数的指针不可能泄漏到运行时代码中,依此类推。

因此,consteval目前没有多大用途。它在a few places like source_location::current(),中使用,这在运行时执行根本没有意义。但归根结底,该功能是进一步编译时编程工具的必要构建块,而这些工具目前还不存在。

这是在paper that originally proposed this feature:

中规定的
然而,推动本论文的是SG7在编译时反射领域所做的工作。现在普遍认为,未来对反射的语言支持应使用constexpr函数,但由于反射函数通常必须在编译时计算,因此它们实际上很可能是直接函数。

相关文章