Recursive operator application ->

The arrow operator is said to be applied recursively. But when I try to execute the following code, it prints gibberish when it should print 4.

class dummy { public: int *p; int operator->() { return 4; } }; class screen { public: dummy *p; screen(dummy *pp): p(pp){} dummy* operator->() { return p; } }; int main() { dummy *d = new dummy; screen s(d); cout<<s->p; delete d; } 
+7
source share
3 answers

What Stanley means by "recursive" is that the statement applies to each returned object until the return type is a pointer.

What happens here on the first try: screen::operator -> returns a pointer. So this is the last call to operator -> that the compiler is trying to execute. Then it resolves the right elements of the operator ( p ) by searching for a member in the return type of the point ( dummy ) with that name.

Essentially, whenever the compiler finds the syntax aᵢ->b in the code, it essentially applies the following algorithm:

  • Is aᵢ pointer type? If so, enable the b *aᵢ element and call (*aᵢ).b .
  • Try again aᵢ::operator ->
    • If successful, set aᵢ₊₁ = aᵢ::operator ->() . Go to 1.
    • On failure, we emit a compilation error.

It’s hard for me to come up with a short, meaningful example when a chain from operator -> invocations even makes sense. Probably the only real use is when you write a smart pointer class.

However, the following toy example at least compiles and gives a number. But I would not really recommend writing such code. This destroys encapsulation and makes kittens cry.

 #include <iostream> struct size { int width; int height; size() : width(640), height(480) { } }; struct metrics { size s; size const* operator ->() const { return &s; } }; struct screen { metrics m; metrics operator ->() const { return m; } }; int main() { screen s; std::cout << s->width << "\n"; } 
+10
source

The C ++ Primer (5th Edition) formulates it as follows on page 570:

The arrow operator never loses its fundamental value of member access. When we overload the arrow, we change the object from which the arrow extracts the specified element. We cannot change the fact that the arrow selects an element.

+1
source

Deal times screen::operator->() returns a pointer ( dummy* ), recursion stops because the built-in (default) -> used in this pointer. If you want recursion, you must return dummy or dummy& from screen::operator->()

0
source

All Articles