Handling Member Pointers in Template Args

Aug 05, 2022

I always forget how to handle member pointers in templates, so here is a recipe:


template <auto>     // since C++17
struct my_template; // Primary template, no definition

template <typename Class, typename ResultType, ResultType Class::* Member>
struct my_template<Member> {
    // optional type aliases
    using class_type = Class;
    using member_type = ResutlType;

    static constexpr auto member = Member;
    // code here
};

For C++20 a non-type concept (cannot be used instead of typename) can be defined as follows:

template<auto P>
concept member_data_pointer = std::is_member_object_pointer_v<decltype(P)>;

template <auto P>
concept member_func_pointer = std::is_member_function_pointer_v<decltype(P)>;

How to use this concept to constrain templates:

// Constraining primary template
// Usable to constrain all specialisations to member data pointers
template <auto P>
requires member_data_pointer<P>
struct my_template;

template <auto P>
struct my_cool_template; // Primary template to handle both data and function members

// Constraining template specialisation to member data pointers
template <typename Class, typename ResultType, ResultType Class::* Member>
requires member_data_pointer<Member>
struct my_cool_template;

// Constraining template specialisation to member function pointers
template <typename Class, typename MemberType, typename... Args, MemberType (Class::*Member)(Args...)>
requires member_func_pointer<Member>
struct my_cool_template;