Search code examples
c++pointer-to-member

how is pointer to member able to bind to T U::*


I was going through std::is_member_pointer in cpprefernce.

template< class T >
struct is_member_pointer_helper         : std::false_type {};
 
template< class T, class U >
struct is_member_pointer_helper<T U::*> : std::true_type {};
 
template< class T >
struct is_member_pointer : 
    is_member_pointer_helper<typename std::remove_cv<T>::type> {};

int main() {
    class cls {};
    std::cout << (std::is_member_pointer<int cls::*>::value
                     ? "T is member pointer"
                     : "T is not a member pointer") << '\n';
    std::cout << (std::is_member_pointer<int(cls::*)(int, int)>::value
                     ? "T is member pointer"
                     : "T is not a member pointer") << '\n';
}

Ouput:

T is member pointer
T is member pointer

How are int cls::* and int(cls::*)(int, int) both bind to T U::* in struct is_member_pointer_helper<T U::*>?

For int cls::* T is int and U is cls and for int(cls::*)(int) what are T and U? I went through this question on SO which has the below code:

template<class MemberT, class ClassT>
using make_member_ptr = MemberT ClassT::*;

class A {
public:
    void member() { }
};

int main()
{   
    make_member_ptr<int, A> ptr;
    make_member_ptr<void(), A> fptr;
    static_assert(std::is_same_v<int A::*, decltype(ptr)>);
    static_assert(std::is_same_v<decltype(fptr), void(A::*)()>);
    return 0;
}

Like werner pointer in the comments how is make_member_ptr<void(), A> expands to void (A::*)()

link to the code


Solution

  • It's easier to understand if you spell the types with words.

    T U::* is a "pointer to member of class U that has type T".

    int(cls::*)(int, int) is a "pointer to member of class cls that has type 'a function with parameters (int, int), returning int'".

    Hence U is cls, and T is a "function with parameters (int, int), returning int", aka int(int, int).