In my last post, I mentioned a problem (choosing between one of several templated classes based on information that won’t be available until runtime) and also mentioned a workaround involving virtual dispatch, in which the templated class extends a non-templated class. This doesn’t address all of the concerns I set out with regard to other solutions, but it is rather cleaner than any of them since it makes conditional dispatch implicit. Here’s an example of this very simple workaround as applied to a trivial class:
// Trivial example of using virtual dispatch to hide template parameters from clients, as
// alluded to here: http://chapeau.freevariable.com/2009/06/a-problem-of-dependent-types.html
#include <iostream>
#include <list>
#include <tr1/memory>
class repr {
public:
virtual ~repr() { }
virtual size_t op() = 0;
};
template <size_t N>
class concrete_repr : public repr {
public:
virtual ~concrete_repr() { }
size_t op() {
return N;
}
};
typedef std::tr1::shared_ptr<repr> p_repr;
typedef std::list<p_repr> repr_list;
typedef repr_list::iterator repr_it;
int main(int c, char *v[]) {
;
repr_list items.push_back(p_repr(new concrete_repr<2>()));
items.push_back(p_repr(new concrete_repr<3>()));
items.push_back(p_repr(new concrete_repr<5>()));
items.push_back(p_repr(new concrete_repr<7>()));
items.push_back(p_repr(new concrete_repr<11>()));
items
for (repr_it it = items.begin(); it != items.end(); ++it) {
std::cout << (*it)->op() << std::endl;
}
}