To clarify a possible precedence ambiguity in the English language: We are taking about "smart (pointer to member)", not "(smart pointer) to member".
I would define a smart pointer to member as a class X with operator ->* (T* lhs, X rhs)
overloaded.
In his article "Implementing operator->* for Smart Pointers", Scott Meyers only briefly touches smart pointer to member, because back then (1999) the specific problem was difficult enough for raw pointer to member (side note: the latter is solved elegantly with lambdas here).
Anyhow, Scott Meyers writes in a footnote:
Shortly after writing the draft of this article, one of my consulting clients showed me a problem that was naturally solved by smart pointers to members. I was surprised, too.
I've tried to find an example for such a natural smart pointer to member. But I could neither come up with anything myself nor did online search uncover what I was looking for.
Do you know of any real world "smart pointer to member" example?
EDIT:
I'm not looking for any ->*
overload (as done by some EDSLs).
Aiming at examples with semantics that resemble the built-in ->*
, my definition above explicitly requires lhs
to be a raw pointer.
You have a layout engine that should work with 90 degree rotation (height and width swapping).
Using smart member pointers you can make (foo->*x)
and (foo->*y)
swap meaning. The same smart x
and y
can work on different unrelated kinds of data (rectangles, points, vectors), even on types you don't own.
template<class F>
struct smart_pm_t {
F f;
template<class T>
friend decltype(auto) operator->*(T* t, smart_pm_t const& self ) {
return self.f(t);
}
};
template<class F>
smart_pm_t<F> smart_pm( F f ) { return {std::move(f)}; }
auto x = smart_pm( [](auto* t)->decltype(auto) noexcept { return t->x; } );
auto y = smart_pm( [](auto* t)->decltype(auto) noexcept { return t->y; } );
and we can get fancier with them.
do_layout( data, x, y );
vs
do_layout( data, y, x );
solves the problem horizontally or vertically.
This is an actual (simplified) use case in actual production code that reduced code duplication and ironed out a whole pile of bugs, because we only had to fix the code once.
A right hand normal member pointer had the problem that we would have to pass an entire suite of member pointers, one per type that works on the left hand side.
In effect, we wrote a compile-time polymorphic member pointer.
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