如果 -> 运算符不 return 像点这样的引用怎么办。操作员?这也会停止重载 -> 运算符吗?

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

历史:为什么我们可以重载 -> 而不是 .操作员?两者都是成员访问操作符,意义相同。

我已经阅读了一些来自

的参考资料

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

Why can operator-> be overloaded manually?

但我的疑问仍然存在,为什么我们可以重载 .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()).opeartor()).operator() 因此 foo 的值设置为 42.

问题:- 如果我拿这个点我还有两点,

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

2) 如果 -> 运算符没有 returns 对 class Y 的引用怎么办?那样的话会不会是编译错误?

在阅读 this:

之后,我才明白重载 operator-> 是如何工作的

The expression E1->E2 is exactly equivalent to (*E1).E2 for built-in types. If a user-defined operator-> is provided, operator-> is called again on the value that it returns, recursively, until an operator-> is reached that returns a plain pointer. After that, built-in semantics are applied to that pointer.

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

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))->.

如果将 Zs 运算符 return 设为指针,递归会在 &(z.y) 处停止,但 Y 没有 foo 并且编译器会报错。