N4527 5.20 [expr.const] p2
条件表达式e是核心常量表达式除非e的评估,遵循规则 抽象机器(1.9),将评估以下表达式之一:
(2.7) - 左值 - 右值转换(4.1),除非它适用于
(2.7.1) - 整数或枚举类型的非易失性glvalue,指的是一个完整的非易失性const 具有先前初始化的对象,使用常量表达式初始化,或
(2.7.2) - 一个非易失性glvalue,引用字符串文字的子对象(2.13.5)或
(2.7.3) - 一个非易失性glvalue,它指的是用constexpr定义的非易失性对象,或者指的是 到这样一个对象的不可变子对象,或
(2.7.4) - 文字类型的非易失性glvalue,引用其生命周期开始的非易失性对象 在评估e;
5.20 [expr.const] P5
常量表达式是 glvalue核心常量表达式,其值指的是一个实体 允许的常量表达式结果(如下定义),或者是一个prvalue核心常量表达式 value是一个对象,对于该对象及其子对象:
- 引用类型的每个非静态数据成员引用一个实体,该实体是常量表达式的允许结果,并且
- 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址,超过此类对象末尾的地址(5.7),函数的地址或空指针值
实体是常量表达式的允许结果,如果它是静态存储持续时间的对象,该对象不是临时对象,或者是其值满足上述约束的临时对象,或者它是一个 功能
void foo(){
const int a = 1;//a has automatic storage duration
int b[a]{};
}
在int b[a]{};
中,a
是一个id-expression,a
是一个左值核心常量表达式。 a
是一个常量表达式吗?
这是对Is a glvalue integral constant expression a constant expression?
的澄清答案 0 :(得分:4)
a
可以是prvalue核心常量表达式,但不是glvalue核心常量表达式,也不应该是可能的。你已经在标准中找到了措辞,所以也许最好解释为什么规则就是这样。
void foo(){
const int a = 1;//a has automatic storage duration
static constexpr const int &ra = a;// cannot possibly be valid
}
这可能无效,因为在 任何a
之前,foo
被调用之前需要知道a
的地址。
你的int b[a]{};
很好,因为它使用a
作为prvalue核心常量表达式:它不关心a
存储在哪里,它只关心它具有什么值。< / p>