Получить базовый класс для типа в иерархии классов

Можно ли получить тип базового класса в иерархии классов?

Например:

struct A{};
struct B{} : public A;
struct C{} : public B;

Мне нужен шаблон, у которого будет typedef Base<T>::Type внутри:

Base<A>::Type == A
Base<B>::Type == A
Base<C>::Type == A

Возможно ли это? Как насчет случая, когда у меня есть множественное наследование?

Ответ 1

Я думаю, std::is_base_of может помочь вам

#include <type_traits>

std::is_base_of<B, D>()

Если D является производным от B или если оба являются одним и тем же неединичным классом, обеспечивает постоянное значение члена, равное true. В противном случае значение ложь.

Вы можете использовать его, чтобы проверить, является ли класс базовым классом другого или нет:

std::is_base_of<A, A>()   // Base<A>::Type == A

std::is_base_of<A, B>()   // Base<B>::Type == A

std::is_base_of<A, C>()   // Base<C>::Type == A

Ответ 2

Классы в С++ могут иметь более одного базового класса, поэтому нет смысла иметь свойство "получить меня базовый".

Однако дополнения TR2 включают новые поддерживаемые компилятором черты std::tr2::bases и std::tr2::direct_bases, которые возвращают непрозрачный список типов базовых классов.

Я не уверен, произойдет ли это в С++ 14 или будет выпущено независимо, но GCC уже похоже, поддерживает это.

Ответ 3

Это может быть хороший способ сделать это, в зависимости от вашего варианта использования. Объявите typedef базового класса с именем base в базовом классе.

Тогда производные классы X наследуют его как typename X::base.

Итак, B::base - A, а C::base - A.

struct A
{
    typedef A base;
};

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

template<class X>
void f()
{
    typename X::base x;
}

int main()
{
    f<B>();
    f<C>();
}