Useful with StaticReflection and StaticPolymorphism. The type has_function receives information about the function signature and stores this in a typedef. Function names are provided in a derived type. SubstitutionFailureIsNotAnError (SFINAE) performs the magic.
The following implementation supports up to 8 parameters - this may be extended as required.
namespace framework {
namespace meta
{
template <
typename T, typename R,
typename A0 = unspecified,
typename A1 = unspecified,
typename A2 = unspecified,
typename A3 = unspecified,
typename A4 = unspecified,
typename A5 = unspecified,
typename A6 = unspecified>
struct has_function
{
// 0-7 arg member function signature
template <
typename U,
typename if_::value,
typename if_::value,
typename if_::value,
typename if_::value,
typename if_::value,
typename if_::value,
typename if_::value,
/* 0 parameter(s) */ R(U::*)(),
/* 1 parameter(s) */ R(U::*)(A0)>::value,
/* 2 parameter(s) */ R(U::*)(A0, A1)>::value,
/* 3 parameter(s) */ R(U::*)(A0, A1, A2)>::value,
/* 4 parameter(s) */ R(U::*)(A0, A1, A2, A3)>::value,
/* 5 parameter(s) */ R(U::*)(A0, A1, A2, A3, A4)>::value,
/* 6 parameter(s) */ R(U::*)(A0, A1, A2, A3, A4, A5)>::value,
/* 7 parameter(s) */ R(U::*)(A0, A1, A2, A3, A4, A5, A6)>::value
>
struct signature;
};
#define FW_HAS_FUNCTION(name)\
template < \
typename T,\
typename R,\
typename A0 = framework::meta::unspecified,\
typename A1 = framework::meta::unspecified,\
typename A2 = framework::meta::unspecified,\
typename A3 = framework::meta::unspecified,\
typename A4 = framework::meta::unspecified,\
typename A5 = framework::meta::unspecified,\
typename A6 = framework::meta::unspecified \
>\
struct has_function_##name : framework::meta::has_function\
{\
template static framework::meta::no check(...);\
template static framework::meta::yes check(signature*);\
enum { value = sizeof(check(0)) == sizeof(framework::meta::yes) };\
};
} // namespace meta
} // namespace framework
For an example, see StaticReflection.
See CeePlusPlusIdioms, TemplateMetaprogrammingTechniques, TemplateMetafunctionIdentity, TemplateMetafunctionAnd, TemplateMetafunctionIf.