代码之家  ›  专栏  ›  技术社区  ›  NoSenseEtAl

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

  •  0
  • NoSenseEtAl  · 技术社区  · 5 年前

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

    我能想到的事情很少:

    • 读者只需读取函数签名,就可以知道函数是在编译时计算的
    • 由于 consteval FN从不在运行时使用(这是推测性的,我没有这方面的实际数据)
    • 不需要强制变量 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 :( 
    }
    
    0 回复  |  直到 5 年前
        1
  •  13
  •   Nicol Bolas    5 年前

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

    然而 constexpr 代码获得了更多的特性,通过 常量表达式 功能。这种想法的一个问题是,不能允许静态反射值泄漏到非编译时代码中。

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

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

    这一功能不可能实现 常量表达式 ,因为 常量表达式 作用 必须 能够在运行时执行。你可以做一些事情,比如获取指向 常量表达式 函数,并以编译器无法跟踪的方式调用它们,从而迫使它在运行时执行。

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

    进来 consteval :一个 "required" to execute only at compile time 。有一些特定的规则,使得指向这些函数的指针不可能泄漏到运行时代码中,等等。

    像这样的 康斯特瓦尔 目前没有什么意义。它被用于 a few places like source_location::current() , 在运行时执行基本上没有意义。但归根结底,该功能是进一步编译时编程工具的必要构建块,而这些工具目前还不存在。

    这是在 paper that originally proposed this feature :

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

    推荐文章