#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;
}