在ubuntu gcc 8.0中:
void bar(){}
constexpr int foo(int a)
{
if (a <=0 )
bar();
return 1;
}
int main()
{
int a1[foo(-1)]; //will give a compile error, which is expected,
//since non-constexpr function is not allowd in constexpr context
}
但是在以下测试中:
int main()
{
int a2[foo(1)]; //no compile error
}
在这里,bar是非constexpr函数。我想知道为什么constexpr上下文中允许使用非constexpr函数,尽管在此测试中未调用它。
constexpr上下文中constexpr函数内部的所有函数都必须是constexpr函数吗?
这取决于。
在函数中允许对非constexpr函数进行调用的事实constexpr
并不意味着对constexpr
函数的所有可能的调用都必须产生一个常量表达式,但是对于需要一个常量表达式的上下文(例如在数组范围内),该调用到constexpr
函数的值必须为常量表达式
该案例的标准相关部分包括:
[dcl.constexpr]/5
对于既没有默认值也没有模板的constexpr函数或constexpr构造函数,如果不存在任何参数值,使得对该函数或构造函数的调用可以是核心常量表达式(8.20)的评估子表达式,或者对于构造函数,则为某个对象(6.6.2)的常量初始化程序,程序格式错误,无需诊断。
[expr.const]/2
表达式e是核心常量表达式,除非按照抽象机(4.6)的规则对e求值将对以下表达式之一求值:
- (2.2)对文字类的constexpr构造函数以外的函数调用,constexpr函数或对平凡析构函数的隐式调用[...]
这意味着constexpr
只要存在一些参数,该函数就可以对非constexpr函数进行调用,因此它可以用作常量数组的表达式或子表达式,这就是为什么可以将其foo(1)
用作数组绑定的值的原因,因为它的评估不涉及调用,bar()
而不是foo(-1)
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句