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::*)()
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)
.