b此代码中的表达式应为核心常量表达式
int main()
{
constexpr int a = 10;
const int &b = a;
constexpr int c = b; // here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于标准说(8.20,第2段[expr.const]在N4700)
表达式
e是核心常量表达式,除非评估e将评估以下表达式之一:
...
除非适用,否则左值 - 右值转换(7.1)
...
非易失性glvalue,引用constexpr定义的非易失性对象,或引用此类对象的不可变子对象,或者
首先,b上面代码中的表达式是一个左值(也是一个glvalue),因为它是一个引用,因此是一个变量(8.1.4.1,第1段[expr.prim.id.unqual]):
如果实体是函数,变量或数据成员,则表达式是左值 ,否则为prvalue; 如果标识符指定位字段(11.5),则它是位字段.
其次,变量b表示的对象是a,并且声明了它constexpr.但是,gcc抱怨道
./hello.cpp: In function ‘int main()’:
./hello.cpp:6:20: error: the value of ‘b’ is not usable in a constant expression
constexpr int …Run Code Online (Sandbox Code Playgroud) 灵感来自这个答案,来自[expr.const]
常量表达式是glvalue核心常量表达式,它指的是一个实体,它是常量表达式的允许结果(如下所定义),或者是一个prvalue核心常量表达式,其值满足以下约束:
如果值是类类型的对象,则引用类型的每个非静态数据成员引用一个实体,该实体是常量表达式的允许结果,
如果值是指针类型,则它包含具有静态存储持续时间的对象的地址,超过此类对象末尾的地址([expr.add]),函数的地址或空指针值,以及
如果值是类或数组类型的对象,则每个子对象都满足这些值的约束.
如果实体是具有静态存储持续时间的对象,则该实体是常量表达式的允许结果,该对象不是临时对象,或者是其值满足上述约束的临时对象,或者它是函数.
什么是具有静态存储持续时间的临时对象?我是否遗漏了某些东西,或者说对象是暂时的并且具有静态存储持续时间是矛盾的吗?
来自[basic.stc.static]的定义
所有没有动态存储持续时间,没有线程存储持续时间且不是本地的变量都具有静态存储持续时间.这些实体的存储应持续该计划的持续时间
仅适用于变量.