Connecting Tech Pros Worldwide Help | Site Map

dynamic_cast inside a template function problem

Newbie
 
Join Date: Mar 2008
Posts: 2
#1: Mar 18 '08
Hello,

Here's my problem. I have a template function where I'd like to set a flag if the passed in data type is derived from a particular base class. The way to typically do this is to use dynamic_cast, unfortunately with PODs and non-polymorphic types coming I can't use the dynamic_cast.

Right now I have a work around that puts the responsibility on the programmer to know whether the input data type is derived from this class.

Any ideas?

Expand|Select|Wrap|Line Numbers
  1.  
  2. class Indexable
  3. {
  4. public:
  5.     virtual ~Indexable();
  6.     virtual void doSomething();
  7.  
  8. }
  9.  
  10.  
  11. template <class T>
  12. void myDesiredFunction(T *ptr)
  13. {
  14.     if(dynamic_cast<Indexable*>(ptr))
  15.     {
  16.          // this is a data type derived from Indexable
  17.     }
  18.     else
  19.     {
  20.          // PODS, non-polymorphic, and classes not derived from  Indexable
  21.      }
  22.  
  23.  
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,164
#2: Mar 18 '08

re: dynamic_cast inside a template function problem


Create a specialisation of the template function for that type.

A specialisation is where you write an implementation of a template function for a specific type (or set of types) that is different from the normal template function, something like this

Expand|Select|Wrap|Line Numbers
  1. class Indexable
  2. {
  3. public:
  4.     virtual ~Indexable();
  5.     virtual void doSomething();
  6.  
  7. }
  8.  
  9. template <class T>
  10. void myDesiredFunction(T *ptr)
  11. {
  12.      // PODS, non-polymorphic, and classes not derived from  Indexable
  13.  
  14. template <>
  15. void myDesiredFunction(Indexable *ptr)
  16. {
  17.      // this is a data type derived from Indexable
  18.  
Newbie
 
Join Date: Mar 2008
Posts: 2
#3: Mar 18 '08

re: dynamic_cast inside a template function problem


Quote:

Originally Posted by Banfa

Create a specialisation of the template function for that type.

A specialisation is where you write an implementation of a template function for a specific type (or set of types) that is different from the normal template function, something like this

Expand|Select|Wrap|Line Numbers
  1. class Indexable
  2. {
  3. public:
  4.     virtual ~Indexable();
  5.     virtual void doSomething();
  6.  
  7. }
  8.  
  9. template <class T>
  10. void myDesiredFunction(T *ptr)
  11. {
  12.      // PODS, non-polymorphic, and classes not derived from  Indexable
  13.  
  14. template <>
  15. void myDesiredFunction(Indexable *ptr)
  16. {
  17.      // this is a data type derived from Indexable
  18.  

I did try that. But when passing derived data types the non-specialized template function gets called instead of the specialized. Is there a way to force it to check the specialized function first even for these cases?
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,164
#4: Mar 18 '08

re: dynamic_cast inside a template function problem


static_cast you derived class pointer to a base class pointer when calling the function.
Newbie
 
Join Date: Feb 2008
Posts: 28
#5: Mar 18 '08

re: dynamic_cast inside a template function problem


Quote:

Originally Posted by jfradley

I did try that. But when passing derived data types the non-specialized template function gets called instead of the specialized. Is there a way to force it to check the specialized function first even for these cases?

What you need is a little boost magic.

http://cci.lbl.gov/~rwgk/shortcuts/b...s_base_of.html
http://www.boost.org/libs/mpl/doc/refmanual/if.html

What you can do in this case is get the "if" object to return an empty function object if the input isn't derived from your base, and it will return the function object that does whatever it is you want it to if the input is derived. Since this is all done at compile time it is pretty efficient I reckon.

If you don't have boost installed, then you will probably find it pretty useful generally so it is well worth it.
Reply