шаблонный полиморфизм через не-шаблонный базовый класс - PullRequest
0 голосов
/ 08 января 2012

У меня следующая ситуация:

class Base2
{
};

class Base1
{
    virtual void f()=0;
protected:
    boost::shared_ptr<Base2> base2Ptr;
};


class Derived1 : public Base1
{
    Base1(boost::shared_ptr<Base2> b2)  : base2Ptr(b2) { }

    void f()
    {
        /* Here I would like to know the derived type of base2Ptr */
    }
}

template<typename T>
class Derived2 : public Base2
{
    typedef T result_type;
}

Ответы [ 2 ]

1 голос
/ 08 января 2012

(Я поместил некоторый код на ideone (Отредактировано, чтобы иметь некоторые виртуальные деструкторы. Это важно для того, чтобы shared_ptr правильно уничтожал DoublyDerived2 в примере.))

На основе комментариев квопрос, я думаю, что конечной целью является, чтобы конструктор Derived1 каким-то образом «знал» и «запоминал» тип static объекта, переданного в конструктор Derived1.В частности:

Derived2<string> *p = new DoublyDerived2<string>();
// static type of p is Derived2, not DoublyDerived
shared_ptr<Base1> x = something_that_creates_a_Derived1(p);

Объект Derived1 должен знать, что p имеет тип Derived2, а не просто имеет тип Base2

Предполагая, что это правильное понимание проблемы, этот код на ideoneдолжен решить это.Основная хитрость заключается в том, что make_Derived1 является шаблоном, а выведенный тип используется при создании Derived1.Derived1 сам по себе является шаблоном, который гарантирует, что его метод foo знает тип.

template <class T>
shared_ptr<Base1> make_Derived1(shared_ptr<T> ptr) {
    cout << typeid(ptr).name() << endl;
    return shared_ptr<Base1>(new Derived1<T>(ptr));
}

и использование:

int main() {
    shared_ptr< Derived2<string> > p ( new DoublyDerived2<string>() ) ;
    shared_ptr<Base1> x = make_Derived1(p);
    x->f(); // prints something like "Derived2", as desired.
}
1 голос
/ 08 января 2012

Нет никакого способа для Derived1<T>::f() получить typedef от Base2*.

Derived2 действительно есть typedef result_type, но на уровне языка нетспособ гарантировать, что отдельный подкласс Base2 также будет иметь typedef с именем result_type.C ++ является статически типизированным языком, поэтому вы не можете писать код, основанный на типе, который может динамически меняться в зависимости от того, какой подкласс находится внутри Base2*.

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