As Edward Diener, the creator of the library, informs us in this thread :
TTI cannot identify inherited member functions even if they are public.
So since you still want to use TTI, let's make a work around. I'll be using an example similar to the related manual pages in BOOST, only inheritance will be added to the 'problem' :
struct AClass { };
struct Top {
int function1();
AClass function2(double, short *);
};
struct Top2 : Top {
long function2(Top &, int, bool, short, float);
Top * function3(long, int, AClass &);
};
int main()
{
cout << has_member_function_function1<Top, int>::value << endl;; // 1. true
cout << has_member_function_function1<Top2, int>::value << endl; // 2. false
return 0;
}
Case (2) is an error since a function named function1
returning an int
is defined in the base class of Top2
, class Top
1. Mechanism to check across a hierarchy of classes
First step will be to build a mechanism that would apply TTI checks to an arbitrary number of classes :
template <
template <class, class, class, class> class check,
typename Ret, typename... Bases
>
struct has_m_f;
template <
template <class, class, class, class> class check,
typename Ret, typename Base
>
struct has_m_f <check, Ret, Base>
{
static const bool value = check<Base, Ret,
boost::mpl::vector<>, boost::function_types::null_tag>::value;
};
template <
template <class, class, class, class> class check,
typename Ret, typename Base, typename... Bases
>
struct has_m_f <check, Ret, Base, Bases...>
{
static const bool value = check<Base, Ret,
boost::mpl::vector<>, boost::function_types::null_tag>::value
|| has_m_f<check, Ret, Bases...>::value;
};
has_m_f
is a struct that forwards an arbitrary length of classes to has_member_function_...
structs, which will be doing the check. No algorithm is added, just a mechanism to elevate the predicate using existential quantification :
if any of the classes ascending the hierarchy has such a member function then return true
With this tool, in your case, you could write
has_m_f < has_member_function_function1, int, Top2, Top >::value;
The template arguments are :
- The struct that checks for the member function (eg
has_member_function_function2
)
- The return type of the function
- Arbitrary number of classes in the hierarchy
2. Auto producing the base classes
The above workaround suffers from the fact that you have to manually supply the base classes. When practicing generic programming, being specific is a drawback.
A way to have this kind of introspection is through std::tr2::bases. If you have an implementation that supports it (it's going to be standard in a "while") you can at last have your introspection using TTI :
has_m_f < has_member_function_function1, int, Top2,
std::tr2::bases<Top2>::type >::value;
HTH