获取所有基类[元编程]

时间:2017-03-25 18:16:34

标签: c++ boost metaprogramming template-meta-programming boost-mpl

昨天遇到了如何从某个类获取所有基类的问题。 例如:

class Object 
{
public:
   Object() = default;
};

class DerivedOne
   : public Object
{
public:
   DerivedOne() = default;
};

class DerivedTwo
   : public Object
   , public DerivedOne
{
public:
   DerivedTwo() = default;
};

我想在typelist =>中获取DerivedTwo的所有基类; {Object,DerivedOne,Object} 需要多次拒绝来自Object类的继承。

有人有这样的经验或知识怎么做?

1 个答案:

答案 0 :(得分:0)

评论中提到了TR2反射提案,该提案已“被放弃”,但已在gcc中实现。下面的代码基于SO帖子:Finding base class at compile time

准备一个元组以容纳从TR2返回的类型

#include<tr2/type_traits>

template<typename T>
struct types_as_tuple;

template<typename... Ts>
struct types_as_tuple<std::tr2::__reflection_typelist<Ts...>>
{
    typedef std::tuple<Ts...> type;
};

检查元组中的重复类型

template<typename T>
struct duplicate_type;

template<typename T1, typename T2, typename... Ts>
struct duplicate_type<std::tuple<T1, T2, Ts...>> {
    constexpr static bool value = std::is_same<T1, T2>::value
                                  || duplicate_type<std::tuple<T1, Ts...>>::value;
                                  || duplicate_type<std::tuple<T2, Ts...>>::value 
};

template<typename T1, typename T2>
struct duplicate_type<std::tuple<T1, T2>> {
    constexpr static bool value = std::is_same<T1, T2>::value;
};

TypesPrinter

template<typename T>
struct TypesPrinter;

template<typename T>
struct TypesPrinter<std::tuple<T>> {
    constexpr TypesPrinter() {
        std::cout << typeid(T).name() << ' ';
    }
};

template<typename T, typename... Ts>
struct TypesPrinter<std::tuple<T, Ts...>> {
    constexpr TypesPrinter() {
        TypesPrinter<std::tuple<T>>();
        TypesPrinter<std::tuple<Ts...>>();
    }
};

主要

struct A {};
struct B: A {};
struct C {};
struct D : B, C, A {};

int main() {
    //---------------------------------------------------------------
    // getting all direct and indirect bases of a class with TR2
    //---------------------------------------------------------------
    using bases_of_D = types_as_tuple<std::tr2::bases<D>::type>::type;

    //---------------------------------------------------------------
    // checking for duplication at compile time
    // (can also use static_assert)
    //---------------------------------------------------------------
    if constexpr(duplicate_type<bases_of_D>::value) {
        std::cout << "duplicate base in class D" << std::endl;
    }

    //---------------------------------------------------------------
    // printing the types
    //---------------------------------------------------------------
    TypesPrinter<bases_of_D>();

}

http://coliru.stacked-crooked.com/a/d556c47c660832ff