什么标准条款要求这个左值到右值的转换?

Lig*_*ica 8 c++ language-lawyer

鉴于:

int main() {
   int x = 0;
   int y = x; // <---
}
Run Code Online (Sandbox Code Playgroud)

可能有人请告诉我的标准(2003年首选)的这条强制要求表达的转换x,从左值右值在对象的初始化y

(或者,如果我错了,并且没有发生这样的转换,那么我也想学习它!)

Dav*_*eas 9

我发现将lvalue-s视为真实对象并将rvalue-s视为存储在对象中的值更容易(如果可能不是100%精确).表达式x是一个左值表达式,它引用x第一行中定义的对象,但当用作非用户定义类型的赋值的右侧时,将读取实际,这是转换的位置从左值到右值执行:读取对象的内容.

至于标准中规定转换的具体条款......好吧,我能想到的最接近的是4.1 [conv.lvalue]/2(左值到右转换):

由左值表示的对象中包含的值是右值结果.

赋值的右侧是rvalue的要求是5.17 [expr.ass]中的隐含或缺失,但是情况或者下面的表达式将是一个错误,因为rhs是一个rvalue并且没有右值到左值的转换:

int x = 5;
Run Code Online (Sandbox Code Playgroud)

编辑:初始化,8.5 [dcl.init]/14,最后一个子弹(指基本类型)状态(强调我的):

  • 否则,正在初始化的对象的初始值是初始化表达式的(可能已转换).[...]

那个意味着读取示例中的左值表达式(即转换为右值).无论如何,前面提到赋值的段落可以在这里应用:如果初始化需要左值而不是右值,则表达式int i = 0;将是格式错误的.

  • 为什么不能根据上下文,两者都不是? (2认同)

Joh*_*itb 8

确实认为这在某种程度上是直观的(其他人已经说过 - 需要价值,因此显然需要将对象指示符转换为其中包含的值).我能想到的最好的是4p3:

当且仅当声明"T t = e;"时,表达式e可以隐式转换为类型T. 对于一些发明的临时变量t(8.5),其形式良好.隐式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果.如果T是引用类型(8.3.2),则结果是左值,否则为右值.当且仅当初始化将其用作左值时,表达式e用作左值.

注意最后的"if if only only" - 初始化器用作rvalue,因为初始化将它用作rvalue(转换结果).所以通过3.10p7

每当左值出现在预期有右值的上下文中时,左值就会转换为右值; 见4.1,4.2和4.3.


编辑:输入4p3的段落可以在8.5p16找到,最后一个子弹:

否则,正在初始化的对象的初始值是初始化表达式的(可能已转换)值.

另请注意以下评论.