[decl.constexpr].5 到底是什么意思?

What does [decl.constexpr].5 mean exactly?

本文关键字:是什么 意思 decl constexpr      更新时间:2023-10-16

constexpr 函数的标准在 [decl.constexpr] 的第 5 点下声明:

对于非模板、非默认的 constexpr 函数或非模板、非

默认、非继承的 constexpr 构造函数,如果不存在参数值,使得函数或构造函数的调用可能是核心常量表达式 (5.19( 的计算子表达式,则程序格式不正确;无需诊断。

它继续给出以下示例:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

我从中得出的结论是,具有空参数列表的函数是无诊断格式错误的。这让我觉得非常奇怪,以至于我怀疑我的理解是不正确的。例如,这是否也是格式不正确的:

constexpr int g() { return 0; }       // ill-formed?

如果是这样,这背后的理由是什么,如果不是,限定意味着什么/constexpr函数何时变得格式不正确?


想必以下都没问题?

constexpr int h(int x) { return x; }  // presumably fine?
constexpr int l = h(42);              // also fine

此规则的基本原理是,至少应该有一个上下文可以在constexpr上下文中评估函数。 例如:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

无法在constexpr上下文中调用f(),因为通过此函数的所有路径都将以不是核心常量表达式的表达式结尾。

编译器必须评估所有可能的调用,以查看是否有任何方法可以在constexpr上下文中使用函数。这通常不容易诊断,因此该语言说它是格式不正确的,不需要诊断,即您做错了什么,但编译器无法诊断它。

请注意,如果f的零参数重载如下:

constexpr int f() { return f(false); }   // ok

这完全没问题,因为评估以核心常量表达式结束。

同样,此函数:

constexpr int g() { return 0; }      // ok

以及这个:

constexpr int h(int x) { return x; }  // ok
constexpr int l = h(42);              // ok

很好,因为可以在constexpr上下文中调用gh

"...如果不存在这样的参数值......">可能会令人困惑,因为您已经询问了g的格式良好。但是g可以用零参数调用,或者换句话说,可以用void参数调用,所以没关系。