在类列表中推导继承关系



给定一个类列表,我需要找到这些类之间的继承关系。例如:

class Animal {};
class Dog : public Animal {};
class Bulldog : public Dog {};
class Cat : public Animal {};
using boost::mp11::mp_list;
template<typename... Class>
using class_bases = ...; // a mp_list of mp_list<Derived, Base>, with void meaning no base
static_assert(
std::is_same_v<
class_bases<Animal, Dog, Bulldog, Cat>,
mp_list<
mp_list<Animal, void>,
mp_list<Dog, Animal>,
mp_list<Bulldog, Dog>,
mp_list<Cat, Animal>
>
>);

我有一个适用于单继承层次结构的解决方案。它是O(n(,并且不使用递归:

template<typename Derived, typename Class>
struct direct_base_impl {
static Class select(Class*);
};
template<typename Derived>
struct direct_base_impl<Derived, Derived> {
static void select(...);
};
template<typename Derived, typename... Class>
struct direct_base : direct_base_impl<Derived, Class>... {
using direct_base_impl<Derived, Class>::select...;
using type = decltype(select(std::declval<Derived*>()));
};

static_assert(
std::is_same_v<
direct_base<Bulldog, Animal, Dog, Bulldog>::type,
Dog
>);
template<typename... Class>
using class_bases = mp_list<
mp_list<
Class,
typename direct_base<Class, Class...>::type
>...
>;

不幸的是,这种方法在存在多重继承的情况下不起作用。

我编写了一个使用暴力的解决方案。它有效,除了直接和间接继承相同基的类。我不关心这种情况,因为在我的上下文(yomm2开放多方法库(中,它无论如何都没有意义。更令人讨厌的是,该解决方案具有O(n^3(最坏情况";性能";,在MI存在下。

有人知道这个问题的解决方案吗,或者有想法吗?

在这种情况下,还有一些额外的基于SFINAE的手势用于处理多重继承。

幸运的是,你不需要自己做,因为std::is_base_of已经为你做了:

std::is_base_of<A、 B>:即使A是私有的、受保护的,B.的或模糊基类

强调挖掘。只需重新实现您的模板以使用std::is_base_ofstd::is_base_of_v,它将代表您处理多重继承。

最新更新