【发布时间】:2017-08-18 09:22:35
【问题描述】:
对于第一个选项(点),第一个表达式应该是一个glvalue 具有完整的类类型。对于第二个选项(箭头)第一个 表达式应为具有指向完整类类型的指针的纯右值。 表达式 E1->E2 被转换为等价形式 (*(E1)).E2; [expr.ref] 的其余部分将仅处理第一个选项 (dot).68 在任何一种情况下,id 表达式都应命名 类或其基类之一。 [ 注:因为一个名字 类被插入到它的类范围内(子句 [class]),一个类的名字 类也被认为是该类的嵌套成员。 —— 尾注 ] [ 注意:[basic.lookup.classref] 描述了如何查找名称 之后 。和 -> 运算符。 — 尾注 ]
根据本段,左值到右值的转换应用于下面sn-p 中的p。但不适用于a。为什么标准规定第一个选项(点)为左值,第二个选项(箭头)为纯右值?
struct A{ void f() {} };
A a;
A* p = new A;
int main() {
a.f();
p->f();
}
【问题讨论】:
-
...为什么应该呢?不清楚你的问题的意义是什么。
-
我试着记住我是否关心过
.或->左边的表达式是LValue 还是RValue。如果两者都没有重载,则它必须是 LValue(或者不会产生一个地址,而这又是绝对必要的,以应用正确表达式的“偏移量”)。->可能过载。由于重载->运算符的实现,左侧的 RValue 可能就足够了。 (但是,我很难想象一个实际的例子——可能是我缺乏幻想。)运算符.可能永远不会超载(它被标准禁止)。 -
@Scheff:将
.应用于右值是完全有效的。 -
@Scheff:
string("foo").c_str()。这是合法的,尽管返回值不能在它出现的整体语句之外使用。 -
@Scheff
string("foo")和std::string()是纯右值。至少,它们在 C++14 中。
标签: c++ language-lawyer c++17 lvalue-to-rvalue