在函数声明的情况下,说明constexpr
符是对编译器的断言,声明的函数可以在常量表达式中求值,即可以在编译时求值的表达式。然而,声明内的对象初始化不需要constexpr
在其声明说明符内具有常量表达式。
更短:constexpr
函数可能暗示常量表达式,但常量表达式初始化不需要相关声明具有constexpr
说明符。
您可以在 C++ 标准 [dcl.constexpr] 中检查这一点:
对 constexpr 函数的调用在所有方面都与对等价的非 constexpr 函数的调用产生相同的结果,除了
— 对 constexpr 函数的调用可以出现在常量表达式中[...]
这是确定表达式是否为常量表达式 [expr.const] 的表达式的求值:
表达式e是核心常量表达式,除非e [...]的评估将评估以下表达式之一[...]
声明不是表达式,因此被声明对象的初始化是一个常量表达式,无论声明中是否存在constexpr
说明符。
最后,在 [dcl.constexpr] 中,指定constexpr
函数必须存在可以将其主体作为常量表达式求值的参数:
对于既不是默认值也不是模板的 constexpr 函数或 constexpr 构造函数,如果不存在参数值,则函数或构造函数的调用可以是核心常量表达式 (8.20) 的求值子表达式,或者,对于构造函数,某些对象的常量初始化程序(6.6.2),程序格式错误,不需要诊断。
当您声明constexpr int a
编译器期望a
由常量表达式初始化并且表达式foo({1,2})
是常量表达式时,因此您的代码格式正确。
PS:尽管如此,函数局部变量声明中的声明说明符(static,thread_local=>static)意味着该函数不能被声明constexpr
。