C++ [decl.constexpr].5的确切含义是什么?

C++ [decl.constexpr].5的确切含义是什么?,c++,language-lawyer,constexpr,constexpr-function,C++,Language Lawyer,Constexpr,Constexpr Function,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)

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
上下文中评估函数。e、 g.鉴于:

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
可以,因为可以在
constepr
上下文中调用
g
h


“…如果不存在参数值以致…”的措辞可能会令人困惑,因为您已经询问了
g
的良好格式。但是
g
可以用零参数调用,或者换言之,用
void
参数调用,所以这很好。

这就是由此引发的。我想其他人也可以加入聊天。关于模板也有类似的规则,模板应该有潜在的类型/参数,它是可实例化的(禁止
static\u assert(false);
)。因此,如果在原始示例中删除
throw
,也可以,对吗,如果调用
bool
重载时,参数也为
false
,那就好了。@bitmask-这取决于替换它的内容。将其添加到答案中。是的,您需要用核心常量表达式替换
throw
,调用
f(true)
才能正常。