When dealing with class member function pointers, we can call a function on an object instance with the following syntax:
struct X {
void foo();
};
X x; // Instance
auto f = &X::foo; // Member function pointer
(x.*f)(); // Call function f on x
When having a raw pointer of an instance, the syntax is this:
X *xptr = new X();
(xptr->*f)();
This nicely follows the analogy of a static function call:
x.foo();
x->foo();
However, when I have a smart pointer of the class, this doesn't work:
unique_ptr<X> xsptr(new X());
(xsptr->*f)(); // g++: error: no match for 'operator->*' in 'xsptr ->* f'
I work around this issue by first applying the dereferencing operator, then calling with the .
syntax:
((*xsptr).*f)();
How ugly is this?
Is the compiler supposed to reject the arrow-syntax from above? Because normally (when statically calling a function), it calls operator ->
. Shouldn't ->*
also just call operator ->
?
The compiler error partly answers this question: The error reads as we can overload operator ->*
to call a member function pointer on a dereferenced object, which unique_ptr
doesn't. But this introduces more questions. Why don't smart pointers do this, if the language requires this? Is it intended not to do so because it introduces other issues? And why do we have to write this operator at all instead of implicitly call the member function pointer on the object returned by ->
? (As this is the behavior when writing xsptr->foo()
)