Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use dynamic_cast for template type checking?

Tags:

c++

    template <class T> void checkObject(T genericObject)
    {
      MyClassA* a = dynamic_cast<MyClassA*>(genericObject);
      if (a != NULL)
      {
        //we know it is of type MyClassA
      }
      MyClassB* b = dynamic_cast<MyClassB*>(genericObject);
      if (b != NULL)
      {
        //we know it is of type MyClassB
      }
    }

Is something like this possible? where we have a template type but we want to know it's actual type?

like image 544
tuck Avatar asked Jan 10 '13 20:01

tuck


2 Answers

In the world of templates you probably want to just specialize templates for each of your types instead of doing a runtime check, ie

 template<typename T>
 void foo(T obj);

 template<>
 void foo<MyClassA>(MyClassA obj) {
 }

 template<>
 void foo<MyClassB>(MyClassB obj2) {
 }

This will allow the compiler to generate the correct template at compile time by deducing on your args.

Note this only resolves based on a instance's static type, that is there's no compile-time knowledge that your variable is a MyClassC which inherits from MyClassB and therefore should use the generic form. So this won't work:

  MyClassC* cinstance = new MyClassC();
  foo(cinstance); //compiler error, no specialization for MyClassC

In general this points to a general rule that compile-time and run-time polymorphism are very different systems. Templates deal strictly in the realm of static types without knowledge of inheritance. This may surprise folks coming from Java/C# which have a more seamless integration between the two features.

For run-time specialization of functionality for a class, your options are

  1. Define virtual methods -- may not be appropriate depending if this bit of functionality truly should be a part of this object
  2. Use dynamic_cast (what you're currently doing) -- somewhat frowned upon, but can be the most straight-forward solution that everyone gets.
  3. Visitor Pattern -- a design pattern that uses overloading to resolve to a function of the correct type at run-time.
like image 130
Doug T. Avatar answered Nov 15 '22 08:11

Doug T.


It is possible but MyClassA and MyClassB must have at least one virtual member function in order for dynamic_cast to work. I also believe you actually want to have (T* genericObject) rather than T genericObject in your function's signature (it would make little sense otherwise).

Solutions based on template specializations are OK for static polymorphism, but I believe the question is how to enable run-time detection of the input's type. I imagine that template being called with a pointer which is of a type that is either a superclass of MyClassA or a superclass of MyClassB. Template specialization would fail to provide the right answer in this case.

Anyway, I have a strong feeling that you are trying to do the wrong thing to achieve what you want to achieve (whatever it is). When you post this kind of questions, I suggest you to make clear where you want to go, what is your goal; this one might just be an obstacle along the wrong path.

like image 22
Andy Prowl Avatar answered Nov 15 '22 08:11

Andy Prowl