Estoy tratando de entender cómo aplicar la programación de plantillas (y en algún punto futuro, metaprogramación de plantillas) a escenarios del mundo real. Un problema que estoy encontrando es que las plantillas de C++ y el polimorfismo no siempre juegan juntos de la manera que quiero.¿Se puede utilizar el polimorfismo de plantilla en lugar del polimorfismo de OO?
Mi pregunta es si la forma en que estoy tratando de aplicar la programación de la plantilla es incorrecta (y debería usar el viejo OOP normal) o si todavía estoy atrapado en el modo de pensar OOP.
En este caso particular, estoy tratando de resolver un problema utilizando el patrón de estrategia. Me sigo encontrando con el problema donde termino deseando que algo se comporte de forma polimórfica, que las plantillas no parecen soportar.
programación orientada a objetos utilizando la composición:
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));
}
}
Potencial Plantilla Versión:
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));
}
}
Cuando intento para convertir la aplicación orientada a objetos a una aplicación basada en la plantilla, el código del interpolador se puede traducir sin Mucho dolor. Básicamente, reemplace las "interfaces" con los parámetros del tipo de plantilla y agregue un mecanismo para pasar una instancia de Strategy/DataSource o parámetros de configuración.
Pero cuando llego al "principal", no me queda claro cómo se debe escribir para aprovechar las plantillas en el estilo de la meta programación de plantillas. A menudo quiero usar el polimorfismo, pero no parece funcionar bien con las plantillas (a veces, parece que necesito los genéricos de borrado de tipos de Java ... ugh).
Cuando a menudo encuentro que quiero hacer es tener algo como TemplateType<?,?> x = new TemplateType<X,Y>()
donde a x no le importa lo que X, Y es.
De hecho, este es a menudo mi problema cuando uso plantillas.
- ¿Debo aplicar un nivel más de plantillas ?
- ¿Estoy tratando de usar mi nueva y brillante llave de plantilla de energía en para instalar un clavo OOP en una ranura PCI?
- ¿O solo estoy pensando en esto todo incorrecto cuando se trata de la programación de la plantilla ?
[Editar] Algunas personas han señalado que esto no es realmente una metaprogramación de plantillas, así que he reformulado la pregunta ligeramente. Tal vez eso sea parte del problema: todavía tengo idea de lo que realmente es TMP.
+1 para señalar que esto no es meta-programación de plantilla. –