【C++】模版元编程例子

已知一批类型 A,B,C,D… 给定任意一个类型T, 如果T是这批类型中任意一个的子类,则返回其对应父类,否则返回T。

#include <iostream>
#include <type_traits>

class BaseA{};
class BaseB{};
class BaseC{};
class BaseD{};

template<class T, int8_t = (std::is_base_of<BaseA,T>::value)?1:
        (std::is_base_of<BaseB,T>::value)?2:
        (std::is_base_of<BaseC,T>::value)?4:
        (std::is_base_of<BaseD,T>::value)?8:0>
struct IsDeriveFromBase{
    typedef T type;
};

template<class T>
struct IsDeriveFromBase<T,1>{
    typedef BaseA type;
};

template<class T>
struct IsDeriveFromBase<T,2>{
    typedef BaseB type;
};

template<class T>
struct IsDeriveFromBase<T,4>{
    typedef BaseC type;
};

template<class T>
struct IsDeriveFromBase<T,8>{
    typedef BaseD type;
};

class DeriveA:public BaseA{};
class DeriveB:public BaseB{};
class DeriveC:public BaseC{};

class NoBase{};

int main(){
    std::cout << typeid(IsDeriveFromBase<DeriveA>::type).name() << std::endl;
    std::cout << typeid(IsDeriveFromBase<DeriveB>::type).name() << std::endl;
    std::cout << typeid(IsDeriveFromBase<DeriveC>::type).name() << std::endl;
    std::cout << typeid(IsDeriveFromBase<BaseA>::type).name() << std::endl;
    std::cout << typeid(IsDeriveFromBase<NoBase>::type).name() << std::endl;
}   

更好的做法是:

template <typename Base, typename Derived, bool = std::is_base_of_v<Base, Derived>>
struct ExtractBaseType {
  static constexpr bool value = false;
  typedef Derived type;
};

template <typename Base, typename Derived>
struct ExtractBaseType<Base, Derived, true> {
  static constexpr bool value = true;
  typedef Base type;
};

template <typename Derived, typename Base, typename... OtherBases>
struct ExtractBaseTypes
    : public std::disjunction<ExtractBaseType<Base, Derived>, ExtractBaseType<OtherBases, Derived>...> {};

template <typename Derived, typename Base, typename... OtherBases>
using ExtractBaseTypes_t = typename ExtractBaseTypes<Derived, Base, OtherBases...>::type;
发布了391 篇原创文章 · 获赞 14 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105416006