#c #c 11
#c #c 11
Вопрос:
Для краткости это упрощенная иерархия:
class IBase
{
public:
virtual ~IBase() = 0 { };
}; // eo IBase
class IDerived : public virtual IBase
{
public:
virtual ~IDerived() = 0 { };
}; // eo IDerived
class Base : public virtual IBase
{
public:
Base() { };
virtual ~Base() { };
}; // eo Base
class Derived : public IDerived
, public Base
{
}; // eo Derived
И функция для определения, реализует ли конкретный указатель на класс переданный «интерфейс»:
template<typename T>
bool same(IBase* base)
{
if(std::is_base_of<T, decltype(*base)>::value)
return true;
return false;
};
И пример:
IDerived* i(new Derived());
bool isSame = same<IDerived>(i);
Я знаю, что могу неправильно использовать decltype
здесь. Кажется, что бы я ни пытался, std::is_base_of<B,D>::value
это всегда false
. Я хочу, чтобы эта функция выполняла, отвечала на вопрос:
Является ли объект, на который указывает, производным от type ( T
), переданного в качестве параметра шаблона?
Ответ №1:
decltype
, например sizeof
, это конструкция времени компиляции. Это означает, decltype(*base)
что даст статический тип выражения *base
, который есть IBase
. Так что то, чего вы намереваетесь достичь, не может быть сделано таким образом.
Я бы предложил такое решение:
template<typename T>
bool same(IBase* base)
{
return dynamic_cast<T*>(base) != nullptr;
};
Комментарии:
1. Спасибо за это. Я надеялся избежать использования dynamic_cast. Но, похоже, на данный момент это правильный путь.
Ответ №2:
template<typename T>
bool same(IBase* base)
{
if(std::is_base_of<T, decltype(*base)>::value)
Это не может работать. decltype(*base)
было бы IBase
(всегда), поэтому оно никогда не будет отражать тип среды выполнения base
.
Вероятно, лучшее, что вы можете сделать, это dynamic_cast<T*>(base)!=0
.