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_<is_same<A6, unspecified>::value, typename if_<is_same<A5, unspecified>::value, typename if_<is_same<A4, unspecified>::value, typename if_<is_same<A3, unspecified>::value, typename if_<is_same<A2, unspecified>::value, typename if_<is_same<A1, unspecified>::value, typename if_<is_same<A0, unspecified>::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<T,R,A0,A1,A2,A3,A4,A5,A6>\ {\ template <typename U> static framework::meta::no check(...);\ template <typename U> static framework::meta::yes check(signature<U, &U:: name >*);\ enum { value = sizeof(check<T>(0)) == sizeof(framework::meta::yes) };\ }; } // namespace meta } // namespace frameworkFor an example, see StaticReflection.
See CeePlusPlusIdioms, TemplateMetaprogrammingTechniques, TemplateMetafunctionIdentity, TemplateMetafunctionAnd, TemplateMetafunctionIf.