Использование std :: is_base_of с decltype в иерархии классов - PullRequest
0 голосов
/ 01 ноября 2011

Для краткости, это упрощенная иерархия:

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. Я хочу, чтобы эта функция отвечала на вопрос:

Является ли указанный объект производным от типа (T), переданного в качестве параметра шаблона?

Ответы [ 2 ]

6 голосов
/ 01 ноября 2011

decltype, как и sizeof, является конструкцией времени компиляции. Это означает, что decltype(*base) даст static тип выражения *base, которое равно IBase. То, чего вы намерены достичь, не может быть сделано таким образом.

Я бы предложил это решение:

template<typename T>
bool same(IBase* base)
{
     return dynamic_cast<T*>(base) != nullptr;
};
1 голос
/ 01 ноября 2011
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...