c++ - constexpr 上下文中的 constexpr 函数内的所有函数都必须是 constexpr 函数吗?
问题描述
在 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
函数必须计算为常量表达式
本案例标准的相关部分为:
[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)
。
推荐阅读
- html - 如何在鼠标悬停时更改垫表的字体颜色
- python - 使用 Docker API for Python 时出现“URL 超出最大重试次数:/v1.35/containers/create”错误
- react-native - 如何使用 react-native-svg 和 Animated 为 gradientTransform 属性设置动画
- rust - 我如何找出命名生命周期的来源?
- maven - 如何为 Maven 配置 client-maven-plugin?
- c - Mellanox libvma:如何接收与用户空间时间相当的数据包时间戳?
- android - Android 中的 Amazon Cognito 用户池和 Facebook 登录
- javascript - 如何使用 Ajax 在 Flask 中显示返回的输入?
- python - tkinter 中的命令功能无法正常工作
- python - pandas groupby - 组名而不是数字