Bel*_*loc 3 c++ language-lawyer
根据[expr.ref] /(4.2)和A()prvalue 的事实,我们得出结论,它A().a[0]是一个xvalue.见下面突出显示的句子
如果E2是非静态数据成员并且E1的类型是"cq1 vq1 X",并且E2的类型是"cq2 vq2 T",则表达式指定由第一表达式指定的对象的命名成员.如果E1是左值,则E1.E2是左值; 否则E1.E2是一个x值.让符号vq12代表vq1和vq2的"联合"; 也就是说,如果vq1或vq2是易失性的,则vq12是易失性的.同样,让符号cq12代表cq1和cq2的"联合"; 也就是说,如果cq1或cq2是const,则cq12是const.如果E2被声明为可变成员,那么E1.E2的类型是"vq12 T".如果E2未被声明为可变成员,那么E1.E2的类型是"cq12 vq12 T.
因此下面的代码段应该编译.代码不能在GCC中编译,也不在VS2017中编译,但它在clang中编译.
#include<iostream>
struct A
{
int a[3];
A(): a{1, 2, 3} {}
};
int main()
{
int &&r = A().a[0];
std::cout << r << '\n';
}
Run Code Online (Sandbox Code Playgroud)
但是,[expr.sub]/1中的措辞表明这a[0]是一个左值,不论其值类别如何A(),这对我来说似乎是不正确的.
后缀表达式后跟方括号中的表达式是后缀表达式.其中一个表达式应为类型为"T的数组"的glvalue或类型为"指向T的指针"的prvalue,另一个应为未编组枚举或整数类型的prvalue.结果是"T"型.类型"T"应该是完全定义的对象类型.66 表达式E1 [E2]与*((E1)+(E2))相同(注意:有关数组*和+和11.3.4的详细信息,请参见8.5.2和8.5.6.-end note],除了在数组操作数的情况下,如果该操作数是左值,则结果为左值,否则为x值.表达E1在表达E2之前测序.
没有矛盾,你只是错误地解析表达式.如果我理解正确的话,你说,E1是A()和E2是a[0]这是不是这种情况.
实际上E2是a.因为.并且[]具有相同的优先级,所以表达式被解析为(A().a)[0].
这意味着根据[expr.ref] p4.2,A().a是一个xvalue(数组类型),因此per [expr.sub] p1 (A().a)[0]因此是一个xvalue.
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |