Here is my code example:
class X
{
public:
        void f() {}
};
class Y : public X
{
public:
        X& operator->() { return *this; }
        void f() {}
};
int main()
{
        Y t;
        t.operator->().f(); // OK
        t->f(); // error C2819: type 'X' does not have an overloaded member 'operator ->'
                // error C2232: '->Y::f' : left operand has 'class' type, use '.'
}
Why the compiler is trying to "move the responsibility" for operator-> from Y to X? When I implement X::op-> then I cannot return X there - compile error says "infinite recursion" while returning some Z from X::op-> again says that Z doesn't have operator->, thus going higher and higher in hierarchy.
Can anyone explain this interesting behavior? :)
The class member access operator (->) can be overloaded but it is bit trickier. It is defined to give a class type a "pointer-like" behavior. The operator -> must be a member function.
Most can be overloaded. The only C operators that can't be are . and ?: (and sizeof , which is technically an operator). C++ adds a few of its own operators, most of which can be overloaded except :: and .
The -> is called the arrow operator. It is formed by using the minus sign followed by a greater than sign. Simply saying: To access members of a structure, use the dot operator. To access members of a structure through a pointer, use the arrow operator.
This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.
The problem is that operator -> is supposed to return a pointer, not a reference.  The idea is that operator -> should return a pointer to the real object that should have the pointer applied to it.  For example, for a class with an overloaded operator ->, the code
myClass->myValue;
translates into
(myClass.operator-> ())->myValue;
The problem with your code is that operator -> returns a reference, so writing
myClass.operator->().f();
is perfectly legal because you're explicitly invoking the operator, but writing
myClass->f();
is illegal, because the compiler is trying to expand it to
myClass.operator->()->f();
and the return type of operator-> isn't a pointer.
To fix this, change your code so that you return a pointer in operator ->.  If you want to overload an operator to return a reference, overload operator *; pointer dereferences should indeed produce references.
Because that's how overloaded -> works in C++.
When you use overloaded ->, expression a->b is translated into a.operator->()->b. This means that your overloaded operator -> must return something that will itself support another application of operator ->. For this reason a single invocation of overloaded -> might turn into a long chain of invocations of overloaded ->s until it eventually reaches an application of built-in ->, which ends the chain.
In your case you need to return X* from your overloaded ->, not X&.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With