Trivia impact: real
The Arrow That Is Not a Pointer
an object uses -> twice before an actual pointer appears
struct Item {
int value = 42;
};
struct Arrow {
Item* item;
Item* operator->() const { return item; }
};
struct Handle {
Item item;
Arrow operator->() { return {&item}; }
};
Handle handle;
std::cout << handle->value << "\n";
Does this compile? What does it print?
Answer
handle is an object, not a pointer, and the chained operator-> calls make the access work.
Why¶
[over.ref] interprets x->m for a class object as (x.operator->())->m when overload
resolution selects that member. Handle::operator->() returns another class object,
Arrow, so the same rule applies again; only Arrow::operator->() finally returns an
Item* for built-in pointer member access. This recursive protocol is why a type need not
be convertible to a raw pointer to support arrow syntax.
Where it shows up¶
Smart pointers, iterators, and proxy handles use this protocol to look pointer-like while managing ownership, validation, or indirection. Most programmers meet it through standard smart pointers; defining a multi-step proxy yourself is much less common.
Takeaway: operator-> may return another arrow-capable object before it returns a pointer.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo