views:

93

answers:

2
struct T
{
        int a;
        int b;
};

class Ptr
{
public:
        Ptr(int a, int b) { t_.a = a; t_.b = b; }
        T* operator->() {return &t_;}
        T& operator*() {return t_;}

private:
        T t_;
};

int main()
{
        Ptr ptr(1, 2);
        cout << "a = " << ptr->a << " b = " << ptr->b << endl;
        cout << "a = " << ptr.operator->()->a << " b = " << ptr.operator->()->b << endl;
} 

Output:

a = 1 b = 2
a = 1 b = 2

Why is ptr->a the same as ptr.operator->()->a, what's the principle in it?

+5  A: 

Because this is how this overloaded operator works...

An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism.

(C++ §[over.ref]/1)

KennyTM
+2  A: 

That's the rule. When overloading operator -> it must return either a pointer or something else that has overloaded operator -> and that operator is applied recursively until a pointer is returned. And the evenutal -> is applied to that pointer. The rule makes sense. Otherwise you'd expect that operator -> take another argument. But of what type? string? Naturally not. I mean, think about it, this is the most (if not only) reasonable way. In this sense operator -> can be said tobe an exception.

Armen Tsirunyan