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 i
myClassIterator->APublicMethodInMyClass()
is nothing but the following:
myClassIterator.operator->()->APublicMethodInMyClass()
The first call to the overloaded operator->
gets you a pointer of some type which has an accessible (from your call-site) member function called APublicMethodInMyClass()
. The usual function look-up rules are followed to resolve APublicMethodInMyClass()
, of course, depending on whether it is a virtual or not.
There is not necessarily a temporary variable; the compiler may or may not copy the pointer returned by &(m_iterator->second)
. In all probability, this will be optimized away. No temporary objects of type MyClass
will be created though.
The usual caveats also do apply to m_iterator
-- make sure that your calls do not access an invalidated iterator (i.e. if you are using vector
for example).
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*