Boost TTI具有非常方便的宏,用于检查类型是否具有成员函数。 See here
但是BOOST_TTI_HAS_MEMBER_FUNCTION对于继承的成员函数返回false。有一个方便的Boost解决方案吗?
我知道自定义SFINAE solution的现有线程。但我更喜欢Boost解决方案,因为我更确定它适用于更多的编译器,我希望避免为每个这样的特定行为维护代码。我也在使用Boost类似的库。
答案 0 :(得分:3)
正如图书馆的创建者爱德华·迪纳(Edward Diener)在this thread中通知我们:
TTI无法识别继承的成员函数,即使它们是公共的。
因此,既然你仍然想要使用TTI,那就让我们来解决。我将使用类似于BOOST中相关手册页的示例,只会将继承添加到“问题”中。 :
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)是一个错误,因为返回function1
的名为int
的函数在Top2
,类Top
第一步是建立一个将 TTI检查应用于任意数量的类的机制:
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
是一个结构,它将任意长度的类转发到has_member_function_...
结构,这将进行检查。没有添加算法,只是一种使用存在量化来提升谓词的机制:
如果任何升级层次结构的类具有这样的成员函数,则返回true
使用此工具,在您的情况下,您可以写
has_m_f < has_member_function_function1, int, Top2, Top >::value;
模板参数是:
has_member_function_function2
)上述解决方法的缺点是您必须手动提供基类。 在练习泛型编程时,具体是一个缺点。
进行这种反省的方法是std::tr2::bases。如果你有一个支持它的实现(它将成为#34;而#34;)你可以最终使用TTI进行内省:
has_m_f < has_member_function_function1, int, Top2,
std::tr2::bases<Top2>::type >::value;
HTH