помогите люди добрые... наставте на путь истинный...
имеется следующуя иерархия (а-ля GoF::Composite)
class YItem {...};
template <typename T> YCollection: public YItem {...};
вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.
т.е. сделать что-то типа
S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.
Через dynamic_cast — никак. YCollection<?> — это не класс (пока вместо знака вопроса не поставишь конкретный параметр).
Но конкретно эту задачу можно решить через виртуальную функцию ( типа bool is_YCollection() ).
S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона. S>т.е. сделать что-то типа
S>
ведь кол-во классов YCollection<T> может быть больше одного... так что похоже никак...
может сделать виртуальную ф-цию? я так понимаю, что currentItem — это YItem (или приводимый к нему)...
и еще, это нужно в рантайме? или при компиляции?
class Base
{
public:
virtual ~Base(){}
};
template<class T>
class Derived : public Base
{};
int main()
{
Derived<int> a;
Derived<int> b;
Base * pb = &a;
Derived<float> * p = dynamic_cast<Derived<float>* >(pb);
Derived<int> * good_p = dynamic_cast<Derived<int> *>(pb);
}
Of course, the code must be complete enough to compile and link.
Здравствуйте, sapunidze, Вы писали:
...
S>возможно ли?
Конечно. Главное, чтобы YItem имел виртуальные функции, и в настройках проекта была включена поддержка rtti.
Вот пример:
class B
{
public:
virtual ~B() {}
};
template<class T>
class D : public B
{
};
int main()
{
B* pb = new D<int>();
D<char>* pd1 = dynamic_cast<D<char>*>(pb);//pd1 == 0
D<int>* pd2 = dynamic_cast<D<int>*>(pb);//pd2 != 0return 0;
}
> class YItem {...};
>
> template <typename T> YCollection: public YItem {...};
>
> > вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона. > т.е. сделать что-то типа > >
Создай специальный нешаблонный класс-тэг именно для идентификации YCollection<> и публично отнаследуй YCollection<> от него. Затем в dynamyc_cast<> приводи к этому тэгу, чтобы узнать, является ли объект YCollection<>.
class YItem {/*...*/};
struct YCollection_tag {};
template <typename T>
class YCollection : public YItem , public YCollection_tag
{/*...*/};
void foo(YItem* item)
{
if(dynamic_cast<YCollection_tag*>(item))
{
// item is YCollection<>
}
}
ME>Создай специальный нешаблонный класс-тэг именно для идентификации YCollection<> и публично отнаследуй YCollection<> от него. Затем в dynamyc_cast<> приводи к этому тэгу, чтобы узнать, является ли объект YCollection<>.
ME>
ME>class YItem {/*...*/};
ME>struct YCollection_tag {};
ME>template <typename T>
ME>class YCollection : public YItem , public YCollection_tag
...
ME>
спасибо, всем откликнувшимся.
отдельное спасибо Maxim Yegorushkin, его вариант мне больше подходит.
Здравствуйте, sapunidze, Вы писали:
S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.
2All обратите внимание на выделеное... S>т.е. сделать что-то типа
так пойдет?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: template & dynamic_cast<>
От:
Аноним
Дата:
03.06.04 16:41
Оценка:
Здравствуйте, sapunidze, Вы писали:
S>здравствуйте,
S>помогите люди добрые... наставте на путь истинный...
S>имеется следующуя иерархия (а-ля GoF::Composite)
S>
S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона. S>т.е. сделать что-то типа
S>
wrote:
> На мой взгляд изящнее сделать иерархию > > > class YItem {...}; > > class YCollectionBase : public YItem{}; > > template <typename T> YCollection: public YCollectionBase {...}; > > if(dynamic_cast<YCollectionBase*>(currentItem))
Согласен, это самое элегантное решение, когда иерерхия абстрактная.
Если же иерархия конкрентная, и конструктор YItem принимает параметры, то у YCollectionBase должен быть fowarding ctor. Здесь может оказаться проще использовать множественное наследование с тэг-классом.