I'm working with a class library where all classes are, directly or indirectly, derived from a base class Base
and have a name. The library provides a facility to search for objects by a name, which will return a Base*
.
Is there any way to find the type of the returned object without checking all possibilities using dynamic_cast
s as I did in the following example? I'd like to avoid that, if at all possible, since the derived classes have template parameters, which makes for quite a few possibilities.
It would also be fine if I were at least able to find out the class type (T1
or T2
, in the example below) without knowing the template type, ie. do something like a dynamic_cast<T1<i_dont_care>*>
.
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
};
template <typename T> class T1 : public Base {};
template <typename T> class T2 : public Base {};
Base *find_by_name() {
return new T2<int>();
}
int main() {
Base *b = find_by_name();
if (T1<int> *p = dynamic_cast<T1<int>*>(b)) {
cout << "T1<int>" << endl;
// do something meaningful with p
} else if (T1<double> *p = dynamic_cast<T1<double>*>(b))
cout << "T1<double>" << endl;
else if (T2<int> *p = dynamic_cast<T2<int>*>(b))
cout << "T2<int>" << endl;
else if (T2<double> *p = dynamic_cast<T2<double>*>(b))
cout << "T2<double>" << endl;
else
cout << "unknown" << endl;
delete b;
return 0;
}
Note that the above example is simplified, ie. in each if
I'd do something meaningful with p
.
I do realize that this is bad design from the very start, however I'm stuck with this library and there's also no way for me to change its implementation.
b
should have a member for doing it. Also you could try inspectingtypeid(*b).name()
. – Longitudep
are all redundant, writeif ( dynamic_cast<T1<int>*>(b) )
– LongitudeBase
really have no other members? This seems like the kind of functionality the library should provide. There is only so much you can do with a plain pointer. – Monochasiumtypeid
idea, thanks. Regarding the redundantp
s, it seems my example was a bit too simplified :). – ScalarBase*
... Man, I thought we were through with the freaking Cylons. – SuribachiBase*
are belong to us – Longitudetypeid(*b).name()
is not guaranteed to be anything in particular. – Logographicdynamic_cast<T1<i_dont_care>*>
." --- this is absolutely impossible. – LogographicT1<?>
and another one if it the type isT2<?>
. – ScalarT1<?>
in C++. You can try parsingtypeid(*b).name()
but this is not portable. – LogographicSubBase
from which your extension classes inherit? You can have one cast to find out if you're dealing with one of your classes, then call the function you want and let inheritance take care of the rest. If it's not one of your classes, well, sucks to be you. – Suribachiclass SubBase:public Base
andSubBase
declares all the helper functions you need. Your classes implementSubBase
. No need for identifiers; just call the functions inSubBase
, if theBase
is aSubBase
. – Suribachitypeid::name()
in the standard is that it can be converted towstring
. No equality or inequality promise of any kind. – Logographic