#include <iostream>
#include <type_traits>
struct Foo
{
// ### Member Function ###
void bar() { std::cout << "Foo::bar()\n"; }
};
// ### 1 Parameter Primary Template (which is empty) ###
template<typename>
struct Traits {};
// ### 2 Parameter Template Specialization ###
template<class T, class U>
struct Traits<T U::*>
^^^^^^ // I don't understand this syntax
{
using type1 = T;
using type2 = U;
};
int main()
{
// ### Pointer to member function ###
void (Foo::*memFuncPtr)() = &Foo::bar;
Foo f;
// ### Use the member function pointer to invoke it ###
(f.*memFuncPtr)();
static_assert(std::is_same_v<void(), Traits<decltype(&Foo::bar)>::type1>);
static_assert(std::is_same_v<Foo, Traits<decltype(&Foo::bar)>::type2>);
return 0;
}
How does the specialization syntax work? It makes sense that the U
in U::*
is the same as the Foo
type but why is T
the same as the void()
type?
Edit
After the very useful comments from @user17732522 and answer by @AnoopRana I was able to change the main
function implementation to use the same syntax (just to see it work).
int main()
{
using F = void();
// ### Pointer to member function ###
F Foo::*memFuncPtr = &Foo::bar;
Foo f;
// ### Use the member function pointer to invoke it ###
(f.*memFuncPtr)();
static_assert(std::is_same_v<void(), Traits<decltype(&Foo::bar)>::type1>);
static_assert(std::is_same_v<Foo, Traits<decltype(&Foo::bar)>::type2>);
return 0;
}
CodePudding user response:
struct Trait<T U::*> ^^^^^^ // I don't understand this syntax
The above syntax means that we've a pointer to a member of a class named U
where the member has type T
. In other words, a pointer to a member of class U
that has type T
.
Now let's apply this to &Foo::bar
. The type of the expression &Foo::bar
is:
void (Foo::* f)()
Now you can compare this with T U::*
So, after comparing we get:
U = Foo
which is the class type.T = void()
which means a function that has the return typevoid
and takes no parameter i.e., a function type.
which effectively means that we've a pointer to a member function that has the return type void
and takes no parameters, of class Foo
.