5

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

我能想到的几件事:

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

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

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 :( 
}
4

1 回答 1

13

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

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

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

但是如果你想写一个接受反射值并返回反射值的函数呢?还是反射值列表?

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

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

输入:仅在编译时“必需”执行consteval的函数。有一些特定的规则使指向此类函数的指针不可能泄漏到运行时代码等中。

因此,consteval目前没有太多目的。它在一些地方使用source_location::current()例如在运行时执行从根本上说没有意义。但最终,该功能是进一步编译时编程工具的必要构建块,这些工具尚不存在。

这在最初提出此功能的论文中有所规定:

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

于 2020-11-08T19:24:23.610 回答