C++ 在下面的代码中,将左值到右值的转换应用于变量“x”不会生成常量表达式。为什么呢?

C++ 在下面的代码中,将左值到右值的转换应用于变量“x”不会生成常量表达式。为什么呢?,c++,language-lawyer,constant-expression,C++,Language Lawyer,Constant Expression,下面的代码片段是由Hubert Tong提供的 extern int globx; int main() { const int &x = globx; struct A { const int *foo() { return &x; } } a; return *a.foo(); } 然后作者写道: x 满足出现在常量表达式中的要求, 但将左值应用于右值会话 x 不会产生一个 恒定表达式 为什么将左值到右值的转换应用于x不会产生

下面的代码片段是由Hubert Tong提供的

extern int globx;
int main() {
    const int &x = globx;
    struct A {
        const int *foo() { return &x; }
    } a;
    return *a.foo();
}
然后作者写道:

x
 满足出现在常量表达式中的要求, 但将左值应用于右值会话 <代码>x 不会产生一个 恒定表达式


为什么将左值到右值的转换应用于
x
不会产生一个常量表达式?

将左值到右值的转换应用于
x
会读取可变全局变量
globx
的值,这使得它不是一个常量表达式,因为
globx
的值会发生变化(而且,即使它是
const
,也会有编译时不知道其值的问题)。当然,这并不奇怪:没有人会期望
int{x}
是一个常量表达式。尽管如此,DR指出这一事实不应该导致odr使用
x
,因此代码应该是格式良好的:由于
x
具有常量初始化,编译器可以将
&x
转换为
&globx

将左值到右值的转换应用到de>x
读取可变全局变量
globx
的值,这使得它不是一个常量表达式,因为
globx
的值可能会发生更改(而且,即使它是
const
,也会出现编译时不知道其值的问题)当然,这并不奇怪:没有人会期望
int{x}
是一个常量表达式。DR指出,尽管如此,这一事实不应导致odr使用
x
,因此代码应该是格式良好的:由于
x
具有常量初始化,编译器只需将
&x
转换为
&globx

globx
的值及其内存ad我看不到“常量表达式”或“左值到右值的转换”在这个code@RemyLebeau我不明白你的意思。
x
确实满足了在常量表达式中出现的要求,那么你想说什么呢?
globx
的值及其内存地址在运行时才知道。我看不到“常量表达式”或“左值到右值转换”在这个code@RemyLebeau我不明白你的意思。
x
确实满足了以常量表达式出现的要求,那么你想说什么呢?当你说“将l-to-r转换应用于
x
时,读取可变全局变量
globx
的值。”,我不同意。将l-to-r转换应用于
x
读取变量
x
,而不是
globx
@JoãoAfonso,我很抱歉,但这毫无意义。标准非常明确地说“读取glvalue指示的对象”引用不是对象。我认为你是对的,因为
x
是一个引用,因此应用于
x
的l-to-r转换读取
globx
的值。你说“没有人会期望
int(x)
是一个常量表达式”是什么意思?@JoãoAfonso我认为大家都清楚
int{x}的值
不是编译时常量。将左值到右值转换应用于
x
基本上是计算
int{x}
。当您说“将l-to-r转换应用于
x
时,读取可变全局变量
globx
的值。”,我不同意。将l-to-r转换应用于
x
读取变量
x
,而不是
globx
@JoãoAfonso,我很抱歉,但这毫无意义。标准非常明确地说“读取glvalue指示的对象”引用不是对象。我认为你是对的,因为
x
是一个引用,因此应用于
x
的l-to-r转换读取
globx
的值。你说“没有人会期望
int(x)
是一个常量表达式”是什么意思?@JoãoAfonso我认为大家都清楚
int{x}的值
不是编译时常量。将左值到右值转换应用于
x
基本上是计算
int{x}