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