I have the following hierarchy:
class base
{
public:
virtual ~base(){}
virtual void foo() {}
};
template <typename T>
class derived1 : public base
{
virtual void foo() {};
};
template <typename T>
class derived2 : public base
{
virtual void foo() {};
};
Now given a pointer to base, I'd like to find out if the underlying is either derived1 or derived2. The problem is that both derived1 and derived2 can be specialised on many different types, using dynamic_cast to test for a down cast requires the template type to be know. I've ended up with messy, unmaintable and incomplete bit of code:
base* b = new derived1<int>();
if (dynamic_cast<derived1<int>*> ||
dynamic_cast<derived1<unsigned int>*> ||
dynamic_cast<derived1<double>*>)
std::cout << "is derived1";
else if (dynamic_cast<derived2<int>*> ||
dynamic_cast<derived2<unsigned int>*> ||
dynamic_cast<derived2<double>*>)
std::cout << "is derived2";
Is there a better way, that can handle any type specialization?
You could add a virtual method to do a meta-type check of some kind:
Solution 1: add one more virtual function:
Solution 2: using tag classes:
Move the logic which depends on the type into the type.
Instead of:
add a
virtual print_name() const
function tobase
, and then do:Insert a non-templated class inbetween
base
andderived1
orderived2
:In a comment, you mentioned:
Add that (virtual) function to
derived1_base
, and you don't even need to knowT
anymore.NOTE: I consider a list of
dynamic_cast<>
a code smell, and I urge you to rethink your approach.