首页 > 解决方案 > 如何理解“明显恒定评估”的定义?

问题描述

P0595介绍了该std::is_constant_evaluated()功能。本文讨论了在某些情况下,包含表达式是常量表达式,但编译器不需要在编译时进行评估。给出的例子是:

constexpr double power(double b, int x) {
  if (std::is_constant_evaluated() && x >= 0) {
    // ...
    // return r;
  } else {
    // Let the code generator figure it out.
    return std::pow(b, (double)x);
  }
}

double thousand() {
  return power(10.0, 3);
}

编译器可以在编译时进行评估power(10.0, 3),但不是必须的。因此,is_constant_evaluated返回 false。

因此,本文引入了“明显恒定评估”的概念:

我们的方法是精确识别一组“明显恒定评估”(一个新的技术短语)的表达式,并指定我们的新函数true在评估此类表达式期间和false其他情况下返回。

具体来说,我们在“明显恒定评估”的表达式集中包含了两种表达式。第一种很简单:标准已经要求常量结果的上下文中的表达式,例如数组的维度或 constexpr 变量的初始化程序。...

这对我来说很有意义。然而,标准中的实际措辞让我感到困惑:

如果满足以下条件,则表达式或转换e显然是常数求值:

  • 一个常量表达式,或者...

换句话说,该标准规定所有常量表达式都是明显的常量求值,这(对我来说)似乎没有包含表达式出现在需要常量表达式的上下文中的要求。提案备注power(10.0, 3)是核心常量表达,也是我的理解;这使它成为一个常量表达式。如果所有常量表达式都明显地被常量评估,那么这里似乎is_constant_evaluated必须返回 true。

我应该如何理解标准中的定义,使其具有与提案意图一致的精确含义?

标签: c++language-lawyerc++20

解决方案


这是我最喜欢的。它没有说“一个常量表达式”。它说“一个常量表达式”。†</sup>

常量表达式是一个语法术语。它是 C++ 语法中强制使用常量表达式的那些地方的替代品。

例如,模板参数的语法(特别是语法)是常量表达式(或type-idid-expression),因此该规则意味着在评估作为模板出现的常量表达式时 -论据,该评估显然是恒定评估的。

相比之下, in 中的语法if constexpr采用constant -expression,它只采用condition。所以这个项目符号不足以覆盖,这就是为什么有一个特殊的额外项目符号来覆盖“constexpr if 语句的条件”。if constexpr


†</sup> 想象一下必须口头回答这个问题。你可以听到连字符,对吧?


推荐阅读