This is indeed the syntax used to specify member pointer types as template parameters.
Suppose you have a class
struct Bar
{
int n;
};
then a pointer to the member Bar::n
would have to have its type declared as int Bar::*
:
int Bar::* p = &Bar::n;
Note that int
refers to the type the pointer points to, and Bar::*
means "pointer to a member of Bar
".
Now the function of your example,
template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // note no comma here
accepts a template argument (just one!), which represents the member pointer type for a class _Class
, pointing to non-static data member of type _Tp
.
This is a template specialization of a class template that has only one template parameter:
template <typename T>
struct _Maybe_wrap_member_pointer
{ };
We can instantiate the specialization using the simple class above like this:
_Maybe_wrap_member_pointer<int Bar::*>
or using decltype
:
_Maybe_wrap_member_pointer<decltype(&Bar::n)>
In both cases, _Tp
is deduced to int
, and _Class
is deduced to Bar
.