Ini*_*l D 3 c++ language-lawyer
int aaa;
int& v = aaa;
int& rf = v;
constexpr int& crf = rf;
int main(){
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么所有编译器都同意这个例子是格式良好的?constexpr 变量不是应该有一个在编译器时可以知道的值吗?既然 的值aaa有一个 Indeterminate 值,为什么这个例子可以被编译器接受?
对于这个例子,在我看来,这相当于问为什么rf可以在常量表达式中使用变量。根据[dcl.constexpr#10],初始化的完整表达式crf应该是一个常量表达式。根据 [expr.const#11]
常量表达式要么是泛左值核心常量表达式,它指的是作为常量表达式(如下定义)的允许结果的实体,要么是其值满足以下约束的纯右值核心常量表达式
如果实体是具有静态存储持续时间的对象,该对象不是临时对象,或者是值满足上述约束的临时对象,或者是非立即函数,则该实体是常量表达式的允许结果。
在这种情况下,由于引用绑定应该绑定到一个泛左值,因此rf应该是一个泛左值核心常量表达式;由于rf指的aaa是具有静态存储期的对象,因此我们只需要检查是否rf为核心常量表达式,由[expr.const#5]决定。由于rf是引用类型的 id 表达式,因此应满足 [expr.const#5.12]
引用变量或引用类型数据成员的 id 表达式,除非该引用具有前面的初始化并且
- 它可用于常量表达式或
- 它的生命周期开始于 E 的评估;
这里必须满足在常量表达式中可用,由[expr.const#4]决定
如果 V 的初始化声明 D 可从 P 和
- V 是常量表达式,
- V 未初始化为 TU 本地值,或
- P 与 D 在同一个翻译单元中。
一个对象或引用在常量表达式中可用,如果它是
- 可用于常量表达式的变量,或
由于rf是引用,因此由于 [expr.const#3],它可能是恒定的
如果变量是 constexpr 或者它具有引用或 const 限定的整数或枚举类型,则该变量是潜在常量。
是否常量初始化由[expr.const#2]决定
变量或临时对象 o 是常量初始化的,如果
- [2.1] 要么它有一个初始化器,要么它的默认初始化导致一些初始化被执行,并且
- [2.2] 其初始化的完整表达式当解释为常量表达式时是一个常量表达式...
的声明rf有一个初始化器,子弹2.1是真的,至此,是否rf为常量表达式已经转向检查其初始化的完整表达式是否为常量表达式。再次,v应为常量表达式;判断是否v为常量表达式的过程类似于rf上面给出的过程。依次是判断初始化器aaa是否是常量表达式,我说是,因为aaa是静态存储持续时间对象并且对其进行评估不会违反[expr.const#5]中定义的任何规则,因此它是一个glvalue核心常量表达式. 因此,v可用于常量表达式,这意味着rf也可用于常量表达式。总之,初始化的全表达式crf是一个常量表达式。
此外,无论rf、v、 或aaa,它们都用作泛左值核心常量表达式,因此在此示例中其值并不重要。
| 归档时间: |
|
| 查看次数: |
63 次 |
| 最近记录: |