2015-03-26 6 views
2

Существует is_base_of, чтобы проверить, является ли класс A базовым классом B. Но что, если у меня нет типа переменной?проверить, имеет ли переменная класс, который имеет конкретный базовый класс

Предположим, что у меня есть пять классов A, B, C, D и E, а D и E - как из A, так и B соответственно. C происходит только от A. Теперь у меня есть указатель на A, и я хочу знать, могу ли я наложить указатель на B. В этом случае я хочу знать, указывает ли мой указатель A на объект D или E, чтобы я может наложить указатель на объект B.

Я пробовал следующее, что не сработало.

void foo(const std::shared_ptr<A> & ptr) { 
    if (std::is_base_of<B, decltype(*ptr)>::value) { 
     doSomething(std::static_pointer_cast<B>(ptr)); 
    } 
} 

Редактировать: foo не является функцией шаблона, A и B являются просто заполнителями для существующих классов.

+4

сужаться, используйте 'dynamic_cast'. Он проверяет вас (будет бросать 'std :: bad_cast') –

+0

@RedAlert Точно! При условии, что существует хотя бы одна виртуальная функция. – Christophe

+3

Ну, 'std :: dynamic_pointer_cast', и будет возвращен нулевой указатель, а не' std :: bad_cast', если он не работает. Но да, для этого требуется проверка времени выполнения. – Wintermute

ответ

-1

Если foo является функцией шаблона, вы должны определить B до A в списке параметров шаблона. Вам также необходимо будет указать тип B при вызове foo.

Если ваш код предоставлен как есть, то вы должны сделать foo шаблон с A, являющимся аргументом для шаблона.

Пример:

#include <memory> 

template <typename B> 
void doSomething(std::shared_ptr<B> &ptr) 
{ 

} 

template <typename B, typename A> 
void foo(const std::shared_ptr<A> & ptr) { 
    if (std::is_base_of<B, decltype(*ptr)>::value) { 
     doSomething(std::static_pointer_cast<B>(ptr)); 
    } 
} 

class A { }; 

class B : public A { }; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::shared_ptr<A> a(new B); 

    foo<B>(a); 

    return 0; 
} 
+0

foo не является функцией шаблона. – gartenriese

Смежные вопросы