Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

typeid in a tempate derived class



  • Hi guys,
    I'm new in C++ and I don't know how to solve this problem.
    I've gooled a lot and I found the "typeid" or "decltype" keyword but I don't understand exactly how to use it.
    I try to explain my problem by example.

    class Base
    {
    public:
      Base() {};
    }
    
    template <class T>
    class Derived: public Base
    {
    public:
      Derived(): Base() {};
      T *value = nullptr;
    }
    
    .....
    //on main I've a pointer to base class
    Base* b;
    // ...the object allocated is a Derived object but I don't know the type <T>
    
    // I can print the type
    qDebug() << typeid(b).name();
    
    // I can static_cast the base pointer to derived class like this
    Derived<int>* my_derived_class = static_cast<Derived<int>*>(b);
    qDebug() << *my_derived_class->value;
    
    // but if I don't know the type T??
    // How to get and use it ???
    Derived<???>* my_derived_class = static_cast<Derived<???>*>(b);
    
    

    Any advice and suggestions will be greatly appreciated.
    Thank you for your time.


  • Moderators

    // but if I don't know the type T??
    // How to get and use it ???

    C++ is a strongly typed language. If you don't know the type you can't use it (properly).
    Think about it from the CPU's perspective - b is some address in memory. There's no way to know what concrete type it is. The only one who can know is you and you're the one telling the CPU what it is with a cast.

    But how are you suppose to know, you might ask. Well, a common way to do it is via some sort of type tagging. You can see this in action e.g. in QEvent,where it has a type() method that lets you know what concrete type it is so you can do stuff like

    if (evt->type() == QEvent::MouseMove) {
        QMouseEvent* mouse_evt = static_cast<QMouseEvent*>(evt);
       // do something with mouse_evt
    }
    


  • @Chris-Kawa
    I can do:

    if (dynamic_cast<Derived<double>*>(b))
      qDebug() << "generics double class";
    else if (dynamic_cast<Derived<int>*>(b))
      qDebug() << "generics int class";
    else
      qDebug() << "unknown class type";
    

    There is no other way instead use a if... else if... else if..... for any types ???


  • Moderators

    There is no other way instead use a if... else if... else if..... for any types ???

    No, but I'm not sure what are you trying to achieve. What do you want to do with that thing after the cast? Maybe a virtual function is what you're looking for? Can you give a specific example of types and what you want to do with them after the cast?



  • @Chris-Kawa
    Yes of course, you are right.
    After the cast I need to set the "value" pointer.

    Base* b1;
    Base* b2;
    //...
    Derived<int>* my_d1 = static_cast<Derived<int>*>(b1);
    Derived<int>* my_d2 = static_cast<Derived<int>*>(b2);
    // I'm linking the value pointer of b2 class to the value pointer of b1 class.
    my_d2->value = my_d1->value;
    

  • Moderators

    The only way I see to write this "genericly" would be to have some virtual QVariant getValue() const and virtual QVariant setValue(QVariant v) in your base class and implement it in Derived.
    This way you wouldn't have to do any casting, simply b2->setValue(b1->getValue()).
    The implementation in Derived would do the cast to T via QVariant's value().


Log in to reply