如果 -> 运算符不返回像点这样的引用怎么办。算子?这也会停止重载 -> 运算符吗?

What if -> operator do not return the reference like dot . operator? Will this stop overloading -> operator as well?

本文关键字:运算符 gt 算子 重载 返回 如果 引用 怎么办      更新时间:2023-10-16

历史:为什么我们可以重载->而不能。运营商吗?两者都是成员访问操作符,具有相同的意义。

我读了一些参考

http://www.stroustrup.com/bs_faq2.html overload-dot

为什么操作符->手动超载?

但是我的疑问仍然是一样的,为什么我们可以重载。operator而不是->?

是因为->操作符隐式地获取了返回指针的引用,从而在链式调用

时进行调用吗?
struct X {
    int foo;
};
struct Y {
    X x;
    X* operator->() { return &x; }
};
struct Z {
    Y y;
    Y& operator->() { return y; }
};
Z z;
z->foo = 42;          // Works!  

z->foo = 42;此调用被转换为((z.operator()). operator()). operator(),因此foo的值被设置为42。

问题:如果我取了这一点,我还有两个点,

1)为什么。(点)运算符不能这样工作?

2)如果->操作符不返回类Y的引用怎么办?在这种情况下,它会是编译错误吗?

我才明白重载操作符->是如何工作的,在阅读了以下内容后:

表达式E1->E2完全等价于(*E1)。E2用于内置类型。如果提供了用户定义的operator->,则对其返回的值再次递归调用operator->,直到到达返回普通指针的operator->。之后,将内置语义应用于该指针。

回答你的第二个问题…让我们再看一遍你的例子:

struct X { int foo; };
struct Y {
    X x;
    X* operator->() { return &x; } // returns pointer 
};
struct Z {
    Y y;
    Y& operator->() { return y; } // returns reference
};
Z z;
z->foo = 42;          // Works!

调用z->求值为z.y。这不是一个指针,因此递归继续:(z.y)->求值为&(z.y.x)。这是一个指针,结果表达式是(&(z.y.x))->

如果你让z操作符返回一个指针,递归在&(z.y)处停止,但Y没有foo,编译器会报错。