How arrow-> operator overloading works internally in c++?

Ryan picture Ryan · May 21, 2012 · Viewed 24.6k times · Source

I understand the normal operator overloading. Compiler can translate them to method call directly. I am not very clear about the -> operator. I was writing my first custom iterator and I felt like the need of -> operator. I took a look at the stl source code and implemented my own like it:

MyClass* MyClassIterator::operator->() const
{
    //m_iterator is a map<int, MyClass>::iterator in my code.
    return &(m_iterator->second);
}

Then I can use an instance of MyClassIterator like:

myClassIterator->APublicMethodInMyClass().

Looks like the compiler does two steps here. 1. Call the ->() method the get a temporary MyClass* variable. 2. Call the APublicMethodInMyClass on the temp variable use its -> operator.

Is my understanding correct?

Answer

David Rodr&#237;guez - dribeas picture David Rodríguez - dribeas · May 21, 2012

The operator-> has special semantics in the language in that, when overloaded, it reapplies itself to the result. While the rest of the operators are applied only once, operator-> will be applied by the compiler as many times as needed to get to a raw pointer and once more to access the memory referred by that pointer.

struct A { void foo(); };
struct B { A* operator->(); };
struct C { B operator->(); };
struct D { C operator->(); };
int main() {
   D d;
   d->foo();
}

In the previous example, in the expression d->foo() the compiler will take the object d and apply operator-> to it, which yields an object of type C, it will then reapply the operator to get an instance of B, reapply and get to A*, after which it will dereference the object and get to the pointed data.

d->foo();
// expands to:
// (*d.operator->().operator->().operator->()).foo();
//   D            C            B           A*