2

N4527 5.20[expr.const]p2

条件表达式 e 是核心常量表达式,除非按照抽象机 (1.9) 的规则对 e 的求值将求值以下表达式之一:

(2.7) — 左值到右值的转换 (4.1),除非它应用于

(2.7.1) —一个整数或枚举类型的非易失性左值,它引用一个完整的非易失性常量对象,该对象具有前面的初始化,用常量表达式初始化,或

(2.7.2) — 引用字符串字面量 (2.13.5) 的子对象的非易失性泛左值,或

(2.7.3) — 一个非易失性泛左值,它指代用 constexpr 定义的非易失性对象,或指代此类对象的非可变子对象,或

(2.7.4) — 文字类型的非易失性左值,指的是一个非易失性对象,其生命周期开始于对 e 的评估;

5.20[expr.const]p5

一个常量表达式要么是一个左值核心常量表达式,其值是指一个实体,该实体是一个常量表达式(如下定义)的允许结果,要么是一个纯右值核心常量表达式,其值是一个对象,对于该对象及其子对象:

— 每个引用类型的非静态数据成员都引用一个实体,该实体是一个常量表达式的允许结果,并且

— 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、此类对象末尾的地址 (5.7)、函数的地址或空指针值。

如果实体是具有静态存储持续时间的对象,该对象不是临时对象或者是其值满足上述约束的临时对象,或者它是一个函数,则该实体是常量表达式的允许结果。

void foo(){
    const int a = 1;//a has automatic storage duration
    int b[a]{};
}

In int b[a]{};,a是一个 id 表达式,a是一个左值核心常量表达式。是a常量表达式吗?


这是对左值整数常量表达式是否是常量表达式的澄清?

4

1 回答 1

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知道的地址,任何.fooa

int b[a]{};很好,因为它a用作prvalue核心常量表达式:它不关心a存储在哪里,它只关心它有什么价值。

于 2015-07-21T11:24:16.560 回答