我有一个基类
template<typename T>
class Base {};
和一些派生类:
class DerivedInt : public Base<int> {}
class DerivedDummy : public Base<Dummy> {}
// where Dummy is some user-defined concrete type
template<typename E>
class DerivedGeneric : public Base<E> {}
我希望编写一个类型特征函数f<DerivedType>::value
,只有当T
类型存在DerivedType
继承自Base<T>
时才返回true。
我觉得SFINAE是要走的路......但我不太熟悉元编程黑魔法。谢谢!
答案 0 :(得分:6)
我相信C ++ 11中的type support templates是您想要的,尤其是std::is_base_of。
答案 1 :(得分:2)
我不确定,如果std::is_base_of
在这种情况下有用,但您肯定可以使用std::is_convertible。
如果存在T
类型,Derived
继承自Base<T>
,则表示Derived
可隐式兑换至{ {1}}。
因此,您可以简单地使用以下解决方案。它是以这种方式进行编译时检测,如果你调用类型的检查函数,它就不会编译,这不符合你的要求。检查此代码:
Base<T>
输出:
#include <iostream>
struct Dummy
{
};
template<typename T>
class Base
{
};
class DerivedInt : public Base<int>
{
};
class DerivedDummy : public Base<Dummy>
{
};
template<typename E>
class DerivedGeneric : public Base<E>
{
};
template <class T>
bool is_derived_from_base_t_impl(Base<T>* impl)
{
return true;
}
template <class Derived>
bool is_derived_from_base_t()
{
Derived* d = nullptr;
return is_derived_from_base_t_impl(d);
}
int main()
{
std::cout<< is_derived_from_base_t< DerivedInt >() <<"\n";
std::cout<< is_derived_from_base_t< DerivedDummy >() <<"\n";
std::cout<< is_derived_from_base_t< DerivedGeneric<float> >() <<"\n";
return 0;
}
但是,如果你这样做:
1
1
1
你会得到:
is_derived_from_base_t< float >();
(VC ++ 11的输出)
答案 2 :(得分:1)
对Mateusz Grzejek解决方案的改进,以提出真正的特质:
template <class T>
std::true_type is_derived_from_base_t_impl(const Base<T>* impl);
std::false_type is_derived_from_base_t_impl(...);
template <class Derived>
using is_derived_from_base_t =
decltype(is_derived_from_base_t_impl(std::declval<Derived*>()));
请注意,它不会处理多重继承。