template & dynamic_cast<>
От: sapunidze Россия  
Дата: 03.06.04 08:00
Оценка:
здравствуйте,

помогите люди добрые... наставте на путь истинный...

имеется следующуя иерархия (а-ля GoF::Composite)

class YItem {...};

template <typename T> YCollection: public YItem {...};


вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.
т.е. сделать что-то типа

if(dynamic_cast<YCollection<T>*>(currentItem))
{
  ...
}


возможно ли?

спасибо.
Re: template & dynamic_cast<>
От: Lorenzo_LAMAS  
Дата: 03.06.04 08:07
Оценка:
Так попробуй!
А так — да.
Of course, the code must be complete enough to compile and link.
Re: template & dynamic_cast<>
От: VVB16 Россия  
Дата: 03.06.04 08:07
Оценка:
Добрый день.

Здравствуйте, sapunidze, Вы писали:

S>имеется следующуя иерархия (а-ля GoF::Composite)


S>
S>class YItem {...};

S>template <typename T> YCollection: public YItem {...};
S>


S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.


Через dynamic_cast — никак. YCollection<?> — это не класс (пока вместо знака вопроса не поставишь конкретный параметр).
Но конкретно эту задачу можно решить через виртуальную функцию ( типа bool is_YCollection() ).

--
Vitaly
Re: template & dynamic_cast<>
От: Oleg A. Bachin Украина  
Дата: 03.06.04 08:12
Оценка:
Здравствуйте, sapunidze, Вы писали:

S>
S>class YItem {...};

S>template <typename T> YCollection: public YItem {...};
S>


S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.

S>т.е. сделать что-то типа

S>
S>if(dynamic_cast<YCollection<T>*>(currentItem))
S>{
S>  ...
S>}
S>


S>возможно ли?


ведь кол-во классов YCollection<T> может быть больше одного... так что похоже никак...
может сделать виртуальную ф-цию? я так понимаю, что currentItem — это YItem (или приводимый к нему)...
и еще, это нужно в рантайме? или при компиляции?
Best regards,
Oleg A. Bachin
Re[2]: template & dynamic_cast<>
От: Lorenzo_LAMAS  
Дата: 03.06.04 08:19
Оценка: +1
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.
Re: template & dynamic_cast<>
От: Bell Россия  
Дата: 03.06.04 08:23
Оценка: +2
Здравствуйте, 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 != 0
   
   return 0;
}



S>спасибо.
Любите книгу — источник знаний (с) М.Горький
Re[2]: template & dynamic_cast<>
От: Lorenzo_LAMAS  
Дата: 03.06.04 08:32
Оценка:
Интересно (ИМХО), что dynamic_cast<Generic_type<T> *> приводит к неявному инстанцированию класса
Of course, the code must be complete enough to compile and link.
Re: template & dynamic_cast<>
От: MaximE Великобритания  
Дата: 03.06.04 09:37
Оценка: 36 (2)
sapunidze wrote:

>
> class YItem {...};
>
> template <typename T> YCollection: public YItem {...};
>

>
> вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.
> т.е. сделать что-то типа
>
>
> if(dynamic_cast<YCollection<T>*>(currentItem))
> {
>   ...
> }
>

>
> возможно ли?

Возможно.

Создай специальный нешаблонный класс-тэг именно для идентификации 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<>
    }
}


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 alpha
Re[2]: template & dynamic_cast<>
От: sapunidze Россия  
Дата: 03.06.04 10:10
Оценка:
Здравствуйте, MaximE, Вы писали:



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, его вариант мне больше подходит.
Re: template & dynamic_cast<>
От: WolfHound  
Дата: 03.06.04 10:24
Оценка:
Здравствуйте, sapunidze, Вы писали:

S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.

2All обратите внимание на выделеное...
S>т.е. сделать что-то типа
так пойдет?
class YItem 
{
public:
    virtual ~YItem(){}
};
class YCollectionTag
{
public:
    virtual ~YCollectionTag(){}
};

template <typename T> 
class YCollection
    :public YItem 
    ,public YCollectionTag
{
};
void is_YCollection(YItem* y)
{
    if(dynamic_cast<YCollectionTag*>(y))
        std::cout<<"YCollection<?>\n";
    else
        std::cout<<"not YCollection<?>\n";
}
int main()
{
    YCollection<int> c1;
    YCollection<float> c2;
    YItem y;
    is_YCollection(&c1);
    is_YCollection(&c2);
    is_YCollection(&y);
    return 0;
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: template & dynamic_cast<>
От: Аноним  
Дата: 03.06.04 16:41
Оценка:
Здравствуйте, sapunidze, Вы писали:

S>здравствуйте,


S>помогите люди добрые... наставте на путь истинный...


S>имеется следующуя иерархия (а-ля GoF::Composite)


S>
S>class YItem {...};

S>template <typename T> YCollection: public YItem {...};
S>


S>вопрос: как, если возможно, спуститья по иерархии вниз... мне в коде необходимо узнать, что данный класс является YCollection<?> и не важно какого именно типа параметр шаблона.

S>т.е. сделать что-то типа

S>
S>if(dynamic_cast<YCollection<T>*>(currentItem))
S>{
S>  ...
S>}
S>

На мой взгляд изящнее сделать иерархию


class YItem {...};

class YCollectionBase : public YItem{};

template <typename T> YCollection: public YCollectionBase {...};

if(dynamic_cast<YCollectionBase*>(currentItem))
Re[2]: template & dynamic_cast<>
От: MaximE Великобритания  
Дата: 03.06.04 17:59
Оценка: 1 (1)
wrote:

> На мой взгляд изящнее сделать иерархию

>
>
> class YItem {...};
>
> class YCollectionBase : public YItem{};
>
> template <typename T> YCollection: public YCollectionBase {...};
>
> if(dynamic_cast<YCollectionBase*>(currentItem))

Согласен, это самое элегантное решение, когда иерерхия абстрактная.

Если же иерархия конкрентная, и конструктор YItem принимает параметры, то у YCollectionBase должен быть fowarding ctor. Здесь может оказаться проще использовать множественное наследование с тэг-классом.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 alpha
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.