C++ [decl.constexpr].5的确切含义是什么?
constexpr函数的标准在[decl.constexpr]的第5点中规定: 对于非模板、非默认的constexpr函数或非模板、非默认、非继承的constexpr构造函数,如果不存在参数值,使得函数或构造函数的调用可能是核心常量表达式(5.19)的求值子表达式,则程序格式错误;无需诊断 接下来给出了以下示例: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 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)
才能正常。