C ++在编译时检查继承

时间:2015-04-09 06:42:53

标签: c++ templates

我有一个基类

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是要走的路......但我不太熟悉元编程黑魔法。谢谢!

3 个答案:

答案 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*>()));

Live demo

请注意,它不会处理多重继承。