You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

常量求值阶段的所有表达式均为常量表达式吗?C++标准示例疑问

C++常量表达式相关疑问解答

先看你给出的示例代码:

constexpr int incr(int& n)
{
    return ++n;
}
 
constexpr int g(int k)
{
    constexpr int x = incr(k); // error: incr(k) is not a core constant
                               // expression because lifetime of k
                               // began outside the expression incr(k)
    return x;
}
 
constexpr int h(int k)
{
    int x = incr(k); // OK: x is not required to be initialized
                     // with a core constant expression
    return x;
}
 
constexpr int y = h(1); // OK: initializes y with the value 2
                        // h(1) is a core constant expression because
                        // the lifetime of k begins inside the expression h(1)

疑问1:h函数中的int x = incr(k);为何在编译期求值也合法?

关键区别在于变量的类型:h里的x是普通自动变量,不是constexpr变量。

  • constexpr变量要求初始化表达式必须是核心常量表达式,但普通自动变量没有这个强制要求。
  • 当h(1)被用来初始化constexpr int y时,整个进入编译期常量求值流程:参数k的生命周期始于h(1)的求值过程中,调用incr(k)修改的是这个生命周期在当前常量求值范围内的非volatile字面类型对象,完全符合核心常量表达式的修改规则。
  • 这里incr(k)只是用来初始化普通变量x,不需要单独满足核心常量表达式的要求——只要整个h(1)的求值过程整体符合核心常量表达式规则,就能合法完成编译期求值。

对比g函数里的constexpr int x = incr(k);,因为x是constexpr变量,必须用核心常量表达式初始化,但incr(k)修改的k的生命周期始于g的参数传递(也就是incr(k)这个表达式之外),违反了核心常量表达式的修改规则,所以报错。

疑问2:常量求值过程中的所有表达式是否都属于常量表达式?

不是。

常量求值是一个执行流程,流程里的子表达式不一定都要满足核心常量表达式的要求——只有当某个子表达式被明确要求必须是核心常量表达式时(比如初始化constexpr变量、作为constexpr模板的实参、用于static_assert的条件等),才需要符合规则。

像h函数里的incr(k),它是常量求值过程中的子表达式,但因为只是用来初始化普通自动变量,不需要单独成为核心常量表达式。只要整个h(1)的求值过程整体符合核心常量表达式的要求,就能用来初始化constexpr变量y。

内容的提问来源于stack exchange,提问作者SomeoneWithPassion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:15:37