Under the "Callable" page at cppreference it states:
Notes: Pointers to data members are Callable, even though no function calls take place.
Pointers to function members makes sense: why are pointers to data members Callable if they can't be called?
Pointers to data members are callable types by definition.
Note that this doesn't refer to the use of the call operator ()
, since data member pointers and member function pointers cannot have the ()
operator applied to them; however they can be invoked.
The exposition-only expression INVOKE
(exposed through std::invoke
) works with any callable type.
For a data member pointer f
, INVOKE(f, t)
expands to t.*f
([func.require] p1.4).
Thus, data member pointers act like a function that returns a member of an object.
They can be very useful as projections in the new C++20 algorithms:
struct S { int x; };
std::vector<S> range = /* ... */;
// sort range using std::ranges::less and using &S::x as a projection
std::ranges::sort(range, {}, &S::x);
Such a call to std::ranges::sort
would sort range
by comparing the x
member of each S
object.
This works because algorithms accept any callable type, not just types with a call operator.
Admittedly, the terminology is very confusing. In hindsight, "callable types" should have been named "invocable types" instead.
There have also been proposals to add a ()
operator to member pointers; most recently, there is P1214: Pointer to Member Functions and Member Objects are just Callables!.