Simplified I have the following class hierarchy:
class BaseVec {
public:
BaseVec() {};
virtual ~BaseVec() {};
virtual double get_double(int i) const = 0;
};
template<typename T>
class Vec : public BaseVec {
public:
Vec() { ... };
~Vec() { ... };
T get(int i) const { ... };
double get_double(int i) const {
return get(i);
};
};
In my project I repeatedly end up with code of the following form:
template<typename T>
double foo_template(void* p) {
Vec<T>* v = reinterpret_cast<Vec<T>*>(p);
// use v which involves calling get
return result;
}
double foo(void* p, int type) {
if (type == 0) {
return foo_template<double>(p);
} else if (type == 1) {
return foo_template<int>(p);
} else if (...) {
// etc.
} else {
//unsupported type
}
}
(I could use a switch and use enums, or first cast p
to BaseVec
and then do dynamic_cast
s, but the logic then remains the same)
This is not ideal to maintain. For example when I add an additional class I want to support I have to add a clause to each of the if-else-if blocks.
One possible way of simplifying this would be to cast p
to BaseVec*
and use the get_double
method. However, since this method is called very often this results in poor performance. Furthermore, this is not alway possible: sometimes I want to call the get
method as the type returned is important.
I experimented with the visitor-pattern, and although, this has some advantages, it still means I have to write a seperate piece of code for each possible template parameter.
Is there some way of making this code easier to maintain?
PS: I don't have (much) control over what comes into foo
. foo
gets called by an external programme (R to be exact). Therefore, I can only pass generic pointers, int, doubles and character vectors to foo
.
PPS: Suggestions for a better title are also welcome.