I've recently come across the need to apply a pointer-to-member to the object designated by an iterator. I've tried the natural syntax :
ite->*ptr = 42;
To my dismay, it didn't compile. Iterators don't overload operator->*
, but more surprisingly neither do smart pointers. I needed to resort to the following clunkiness :
(*ite).*ptr = 42;
Experimenting (see the live example below) has shown that such a syntax seems to be achievable for custom classes, for both pointers-to-members and pointers-to-member-functions, at least since C++14.
Thus :
operator->*
, or is it just an oversight ?operator->*
when defining my own pointer-like classes, or does this same reason apply to me ?Live example -- what compiles, what doesn't, and a proof-of-concept for a custom class.
C++ provides two pointer operators, which are Address of Operator (&) and Indirection Operator (*). A pointer is a variable that contains the address of another variable or you can say that a variable that contains the address of another variable is said to "point to" the other variable.
A pointer to a C++ class is done exactly the same way as a pointer to a structure and to access members of a pointer to a class you use the member access operator -> operator, just as you do with pointers to structures. Also as with all pointers, you must initialize the pointer before using it.
The Address of Operator & The & is a unary operator that returns the memory address of its operand.
* or ->* pointer-to-member operators is an object or function of the type specified in the declaration of the pointer to member. So, in the preceding example, the result of the expression ADerived.
You can overload ->*
with a free function. It doesn't have to be a member.
template <typename P,
typename T,
typename M>
M& operator->* (P smartptr, M T::*ptrmem)
{
return (*smartptr).*ptrmem;
}
Now everything that has unary operator*
defined (iterators, smart pointers, whatever) can also use ->*
. You may want to do it in a bit more controlled fashion, i.e. define it for known iterators, known smart pointers etc. separately.
This will not work for member functions for obvious reasons. One would need to specialize/overload for this case and return a bound std::function
instead:
template <typename P,
typename T,
typename M,
typename ... Arg>
std::function<M(Arg&&...)>
operator->* (P smartptr, M (T::*ptrmem)(Arg... args))
{
return [smartptr,ptrmem](Arg&&... args) -> M
{ return ((*smartptr).*ptrmem)(std::forward<Arg>(args)...); };
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With