Template Metafunction Has Function

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 framework

For an example, see StaticReflection.

See CeePlusPlusIdioms, TemplateMetaprogrammingTechniques, TemplateMetafunctionIdentity, TemplateMetafunctionAnd, TemplateMetafunctionIf.


CategoryCppTemplates CategoryMetaprogramming CategoryCpp


EditText of this page (last edited April 4, 2008) or FindPage with title or text search