[decl.constexpr].5 到底是什么意思?
What does [decl.constexpr].5 mean exactly?
constexpr 函数 的标准在 [decl.constexpr] 的第 5 点中指出:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.
下面继续举例说明:
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
那会很好,因为评估以 core-constant-expression.
结束
同理,这个函数:
constexpr int g() { return 0; } // ok
还有这个:
constexpr int h(int x) { return x; } // ok
constexpr int l = h(42); // ok
很好,因为 g
和 h
可以在 constexpr
上下文中调用。
的措辞“......如果不存在这样的参数值......” 可能会造成混淆,因为你已经问过 [= 的格式是否正确19=]。但是 g
可以用零参数调用,或者换句话说,用 void
参数调用,所以没问题。
constexpr 函数 的标准在 [decl.constexpr] 的第 5 点中指出:
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.
下面继续举例说明:
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
那会很好,因为评估以 core-constant-expression.
结束同理,这个函数:
constexpr int g() { return 0; } // ok
还有这个:
constexpr int h(int x) { return x; } // ok
constexpr int l = h(42); // ok
很好,因为 g
和 h
可以在 constexpr
上下文中调用。
的措辞“......如果不存在这样的参数值......” 可能会造成混淆,因为你已经问过 [= 的格式是否正确19=]。但是 g
可以用零参数调用,或者换句话说,用 void
参数调用,所以没问题。