【问题标题】:What are the advantages of using consteval instead of constexpr function?使用 consteval 代替 constexpr 函数有什么好处?
【发布时间】:2021-02-20 18:46:07
【问题描述】:

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

我能想到的几件事:

  • 读者只需阅读函数签名就知道该函数是在编译时评估的
  • 编译器可能会发出更少的代码,因为consteval fns 在运行时从不使用(这是推测性的,我没有这方面的真实数据)
  • 不需要有变量来强制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 :( 
}

【问题讨论】:

  • 您是在询问consteval 的动机吗?我似乎记得具体的原因是表现和反思。我记得保持constexpr 函数可用于运行时会产生性能成本。我还记得某些类型的反射类型只能在编译时存在或应该只在编译时存在(出于安全原因)。 consteval 将提供一种机制来强制执行此操作。
  • @Justin 对设计不感兴趣,更多不关心语言律师的普通开发人员可以从中获得什么......像斯科特迈耶斯的假设有效的 consteval 书这样的东西:)
  • 我认为普通开发人员不会从consteval中受益。此功能只是为 C++ 中的静态反射奠定基础的一部分,届时它将非常有用。目前,我认为没有太多实际用途(除非您已经指出,当您真正关心不会为某些功能生成程序集时)。

标签: c++ constexpr c++20 consteval


【解决方案1】:

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

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

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

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

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

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

输入consteval:函数"required" to execute only at compile time。有特定的规则使指向此类函数的指针不可能泄漏到运行时代码等中。

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

这是在paper that originally proposed this feature

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

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 2022-01-22
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2018-12-24
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多