Why does overloading -> and returning a pointer not require another dereferencing? [duplicate]

2 weeks ago 11
ARTICLE AD BOX

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*

answered May 21, 2012 at 2:35

David Rodríguez - dribeas's user avatar

5 Comments

Can you point me to a reference on this? Can't seem to find any. Nobody else even mentions it.

2013-03-01T01:38:53.347Z+00:00

@MilindR: 13.5.6/1[...] 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 If x->operator->() yields a pointer, it gets dereferenced, if it yields an object of a type that overloads operator->() that operator gets called.

2013-03-01T04:51:58.413Z+00:00

@MilindR: The accepted answer does say this, although it is not so explicit on the meaning: myClassIterator.operator->()->APublicMethodInMyClass() (second piece of code)

2013-03-01T15:26:32.447Z+00:00

@DavidRodríguez-dribeas: Yes, you can infer some recursion from the second line of accepted answer's code, but it is better explained in your answer (In fact, the recursion was not visible to me until I read yours). Thank you !

2014-03-10T13:13:03.34Z+00:00

All this time I thought I had to manually write the recursion to fetch the pointer. +1 for the odd tidbit.

2014-07-23T06:39:21.437Z+00:00

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).

answered May 20, 2012 at 22:46

dirkgently's user avatar

5 Comments

@Potatoswatter which link should we read? A link to a google search isn't really that helpful.

2012-05-20T23:00:33.59Z+00:00

2012-05-20T23:04:53.403Z+00:00

@Seth well I wrote two of the top three, so take your pick ;v) . But the top one is a good choice.

2012-05-20T23:07:44.147Z+00:00

@Potatoswatter ah thank you, I had never heard of the drill-down behaviour. +1 on your answer.

2012-05-20T23:21:39.387Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article