I am trying to get my head around applying template programming (and at some future point, template metaprogramming) to real-world scenarios. One problem I am finding is that C++ Templates and Polymorphism don't always play together the way I want.
My question is if the way I'm trying to apply template programming is improper (and I should use plain old OOP) or if I'm still stuck in the OOP mindset.
In this particular case, I am trying to solve a problem using the strategy-pattern. I keep running into the problem where I end up wanting something to behave polymorphically which templates don't seem to support.
OOP Code using composition:
class Interpolator {
public:
Interpolator(ICacheStrategy* const c, IDataSource* const d);
Value GetValue(const double);
}
void main(...) {
Interpolator* i;
if(param==1)
i = new Interpolator(new InMemoryStrategy(...), new TextFileDataSource(...));
else if(param==2)
i = new Interpolator(new InMemoryStrategy(...), new OdbcDataSource(...));
else if(param==3)
i = new Interpolator(new NoCachingStrategy(...), new RestDataSource(...));
while(run) {
double input = WaitForRequest();
SendRequest( i->GetValue(input));
}
}
Potential Template Version:
class Interpolator<class TCacheStrategy, class TDataSource> {
public:
Interpolator();
Value GetValue(const double); //may not be the best way but
void ConfigCache(const& ConfigObject); //just to illustrate Cache/DS
void ConfigDataSource(const& ConfigObject); //need to configured
}
//Possible way of doing main?
void main(...) {
if(param==1)
DoIt(Interpolator<InMemoryStrategy,TextFileDataSource>(),c,d);
else if(param==2)
DoIt(Interpolator<InMemoryStrategy,OdbcDataSource>(),c,d)
else if(param==3)
DoIt(Interpolator<NoCachingStrategy,RestDataSource>(),c,d)
}
template<class T>
void DoIt(const T& t, ConfigObject c, ConfigObject d) {
t.ConfigCache(c);
t.ConfigDataSource(c);
while(run) {
double input = WaitForRequest();
SendRequest( t.GetValue(input));
}
}
When I try to convert the OOP implementation to a template-based implementation, the Interpolator code can be translated without a lot of pain. Basically, replace the "interfaces" with Template type parameters, and add a mechanism to either pass in an instance of Strategy/DataSource or configuration parameters.
But when I get down to the "main", it's not clear to me how that should be written to take advantage of templates in the style of template meta programming. I often want to use polymorphism, but it doesn't seem to play well with templates (at times, it feels like I need Java's type-erasure generics... ugh).
When I often find I want to do is have something like TemplateType<?,?> x = new TemplateType<X,Y>()
where x doesn't care what X,Y is.
In fact, this is often my problem when using templates.
- Do I need to apply one more level of templates?
- Am I trying to use my shiny new power template wrench to install a OOP nail into a PCI slot?
- Or am I just thinking of this all wrong when it comes to template programming?
[Edit] A few folks have pointed out this is not actually template metaprogramming so I've reworded the question slightly. Perhaps that's part of the problem--I have yet grok what TMP really is.
See Question&Answers more detail:os