I have difficulties to understand the following code
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
// ...
}
int main()
{
auto lambda = [](int i) { return long(i*10); };
typedef function_traits<decltype(lambda)> traits;
// ...
return 0;
}
which occurs in the answer https://stackoverflow.com/a/7943765/7006673.
Here,
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
seems to indicate a specialization of the template class
template <typename T>
struct function_traits
however, the template parameter list of the specialization template <typename ClassType, typename ReturnType, typename... Args>
is not empty (i.e., is not equal to template <>
).
Can someone please help me to understand, what kind of specialization this is and how the template parameters ClassType
, ReturnType
, and Args
are deduced?
Many thanks in advance.
What kind of specialization this is?
This is a partial specialization. type_traits
is explicitly instantiated with:
T = ReturnType(ClassType::*)(Args...) const
But this T
is dependent on ReturnType
, ClassType
, and Args
. That is why you don't have template <>
in the declaration (that would be a full specialization), but a template declaration with new parameters describing a particular kind of T
.
How the template parameters ClassType, ReturnType, and Args are deduced?
They are deduced when the template is instantiated with an expression that suits this specialization. Here, ReturnType(ClassType::*)(Args...) const
can only be substituted with a pointer to a method.
This is an example of SFINAE.