Czy polimorfizm szablonu można zastosować zamiast polimorfizmu OO?
Próbuję skupić się na stosowaniu programowania szablonów (aw pewnym momencie na metaprogramowaniu szablonów) w rzeczywistych scenariuszach. Jednym z problemów, które odkrywam, jest to, że szablony i polimorfizm C ++ nie zawsze grają razem tak, jak chcę.
Moje pytanie brzmi, czy sposób, w jaki próbuję zastosować programowanie szablonów, jest niewłaściwy (i powinienem używać zwykłego starego OOP) lub czy nadal tkwię w mentalności OOP.
W tym konkretnym przypadku próbuję rozwiązać problem za pomocą wzorca strategii. Wciąż napotykam na problem, w wyniku którego chcę, żeby coś zachowywało się polimorficznie, które szablony wydają się nie obsługiwać.
Kod OOP przy użyciu kompozycji:
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));
}
}
Potencjalna wersja szablonu:
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));
}
}
Kiedy próbuję przekonwertować implementację OOP na implementację opartą na szablonie, kod Interpolatora można przetłumaczyć bez większego bólu. Zasadniczo należy zastąpić „interfejsy” parametrami typu szablonu i dodać mechanizm do przekazywania w instancji Strategy / DataSource lub parametrów konfiguracyjnych.
Ale kiedy przechodzę do „głównego”, nie jest dla mnie jasne, w jaki sposób należy napisać, aby skorzystać z szablonów w stylu meta programowania szablonów. Często chcę korzystać z polimorfizmu, ale wydaje się, że nie gra dobrze z szablonami (czasami wydaje mi się, że potrzebuję generików wymazywania typu Java ... ugh).
Kiedy często stwierdzam, że chcę to zrobić, mam coś takiegoTemplateType<?,?> x = new TemplateType<X,Y>()
gdzie x nie obchodzi, czym jest X, Y.
W rzeczywistości jest to często mój problem podczas korzystania z szablonów.
Czy muszę zastosować jeszcze jeden poziom szablonów?Czy próbuję użyć mojego nowego klucza do szablonów zasilania, aby zainstalować gwóźdź OOP w gnieździe PCI?Czy po prostu myślę o tym wszystkim źle, jeśli chodzi o programowanie szablonów?[Edycja] Kilka osób zauważyło, że nie jest to szablonowe metaprogramowanie, więc nieznacznie przeredagowałem pytanie. Być może jest to część problemu - mam jeszcze wątpliwości, czym naprawdę jest TMP.