对于第一个选项(点),第一个表达式应为glvalue 拥有完整的班级类型。对于第二个选项(箭头)第一个 expression应该是一个带有指向完整类类型的指针的prvalue。 表达式E1-> E2被转换为等价形式(*(E1))。E2; [expr.ref]的其余部分仅解决第一个选项 (点)。 68 在任何一种情况下,id-expression都应该命名一个成员 类或其基类之一。 [注意:因为一个名字 class被插入其类范围(Clause [class]),一个名称 class也被认为是该类的嵌套成员。 - 结束说明] [注意:[basic.lookup.classref]描述了如何查找名称 之后 。和 - >运营商。 - 结束说明]
根据此段落,左值到左值的转化适用于以下代码段中的p
。但它不适用于a
。为什么标准规定了第一个选项(点)的glvalue和第二个选项(箭头)的prvalue?
struct A{ void f() {} };
A a;
A* p = new A;
int main() {
a.f();
p->f();
}
答案 0 :(得分:3)
请记住prvalues可以通过临时实现转换[conv.rval]转换为xvalues:
类型
T
的prvalue可以转换为T
类型的xvalue。此转换通过使用临时对象作为结果评估prvalue,从prvalue初始化类型T
的临时对象(15.2) object,并生成一个表示临时对象的xvalue。T
应为完整类型。 [注意:如果T
是类类型(或其数组),则它必须具有可访问且未删除的析构函数;见15.4。 - 结束记录] [示例:struct X { int n; }; int k = X().n; // OK, X() prvalue is converted to xvalue
- 结束示例]
在引入这个新的prvalue-to-glvalue转换之前,C ++ 14没有将 postfix-expression 作为glvalue的限制。
在这方面,C ++ 11是第一个通过(then-)新的右值引用类型来实现用户可定义的,无约束的右值到左值转换的修订版:auto&& x = f();
生成prvalue { {1}}为xvalue f()
。