Consider the following program:
// P is designed to be some proxy for T
template<class T>
struct P
{
T* operator ->();
};
// PP<T> is designed to be some proxy for the proxy P<T>
template<class T>
struct PP
{
P<T> operator ->();
};
// Any old class
class C
{
int f();
};
int main(int, char**)
{
PP<C> c;
return c->f();
}
This compiles successfully on MSVC6, MSVC8 (beta 2) and Comeau Online.
How is C::f() found? (it is indeed being found, as can be confirmed by
attempting to link it.) By what rule does "c->f()" get interpreted as
"c.operator->().operator->().f()"? Usually one cannot do more than one
"implicit conversion" in one go. Is there a special rule, or indeed a
general rule that I am missing here?
One can seemingly extend the example to further layers of indirection, e.g.
template<class T>
struct PPP
{
PP<T> operator ->();
};
template<class T>
struct PPPP
{
PPP<T> operator ->();
};
then change PP<C> in main to be PPPP<C>.