Template Metafunction Has Function

last modified: April 4, 2008

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


Loading...