tition: to determine the type of the expression "i->hooray", the compiler has to determine the type for "*i". Since i appears in a "class member access" - expression, it uses *(operator->()).
The type of operator-> is not a plain pointer, so it tries to dereference it by using operator-> again. This time on the return of the original operator-> which was Loop<int*> (not to be confused with Loop<int>*).
So it looks at the return of Loop<int*>::operator->() which is Loop<int**>. Still not a pointer, so it uses operator-> again to obtain the dereference (this is still possible as long as we want to evaluate a class member access).
In the next step you get Loop<int***>, which is not a pointer...
and so on.
I could imagine, that the behaviour of this postfix expression evaluation was made to make it possible to implement perfectly transparent smart pointer (anyone? Was this the reason?). Consider the following:
1 2 3 4 5 6 7 8 9 10
|
struct A { int i; A():i(42){} };
struct B { A* operator->() {static A a; return &a;} };
struct C { B operator->() {return B();} };
struct D { C operator->() {return C();} };
int main()
{
C c;
cout << c->i;
}
|
B, C and D are "perfect transparent" smart pointer (well, not really. As *c won't work nicely. But that's another story. They are transparent when it comes to c->i.)
If you want to read up more about the postfix expression, it's in the standard chapter 3.2.4 (for the parsing stuff) and 5.2.5 (for the class member access evaluation.)
Ciao, Imi.