2011-06-06 13 views
6

Tengo un montón de funciones que leen completamente idénticas, excepto una línea de código, que es diferente según el tipo de parámetro de entrada.Plantillas para el código que es similar pero no idéntico?

Ejemplo:

void Func(std::vector<int> input) 
{ 
    DoSomethingGeneral1(); 
    ... 
    DoSomethingSpecialWithStdVector(input); 
    ... 
    DoSomethingGeneral2(); 
} 

void Func(int input) 
{ 
    DoSomethingGeneral1(); 
    ... 
    DoSomethingSpecialWithInt(input); 
    ... 
    DoSomethingGeneral2(); 
} 

void Func(std::string input) 
{ 
    DoSomethingGeneral1(); 
    ... 
    DoSomethingSpecialWithStdString(input); 
    ... 
    DoSomethingGeneral2(); 
} 

Me pregunto cómo podría evitar esta duplicación utilizando un mecanismo de plantilla-similares. Si entiendo la "especialización" correctamente, ¿no evita tener el código de las funciones especializadas dos veces?

+1

no podemos dar un paso audaz a menos que se sepa lo que DoSomethingSpecial realmente se supone que debe hacer. ¿Puedes dar más detalles? Si no es realmente adecuado para personalizarlo, tendremos que trabajar para hacerlo dentro de las interfaces generales y ajustarlo desde la perspectiva de la persona que llama. – sarat

Respuesta

8

aquí vaya ... cambió los parámetros para referirse cias para evitar copias + aseguran que puede utilizar los valores modificados de nuevo en el modo Func()

void DoSomethingSpecial(std::vector<int>& input){} 

void DoSomethingSpecial(int& input){} 

void DoSomethingSpecial(std::string& input){} 

template< typename T > 
void Func(T input) 
{ 
    DoSomethingGeneral1(); 
    DoSomethingSpecial(input); 
    DoSomethingGeneral2(); 
} 
1

Declarar una versión genérica pero sólo definir especializaciones:

template<class T> 
void DoSpecificStuff(T& withWhat); 

template<> 
void DoSpecificStuff(int& withWhat) 
{ 
    //implementation 
} 

template<> 
void DoSpecificStuff(std::vector<int>& withWhat) 
{ 
    //implementation 
} 
3

La mejor manera es hacer Func como plantilla:

template<typename T> 
void Func(T input); 

y la sobrecarga de la DoSomethingSpecial...():

void DoSomethingSpecial(std::string); 
void DoSomethingSpecial(int); 
void DoSomethingSpecial(std::vector<int>); 
4

Creo que no hay necesidad de speciaization plantilla, puede utilizar sencilla sobrecarga de funciones, algo como esto:

void DoSomethingSpecial(const std::vector<int>& input) 
{ 
} 

void DoSomethingSpecial(string s) 
{ 
} 

void DoSomethingSpecial(int input) 
{ 
} 
template <typename T> 
void Func(const T& input) 
{ 
    //DoSomethingGeneral1(); 
    DoSomethingSpecial(input); 
    //DoSomethingGeneral2(); 
} 

int main() 
{ 
    std::vector<int> a; 
    Func(a); 
    Func("abc"); 
    Func(10); 
} 
+0

gracias - ¡Simplemente no podía creer que esto funcionaría, pero lo hace! :) –

3

Como una cuestión de estilo, es posible que desee extraer las partes que son diferentes como una clase de plantilla trivial que se especializa más fácilmente. Como ejemplo de esta técnica, considere su implementación de plantilla favorita de un conjunto desordenado (o hash_set). Tales implementaciones requieren que especialices una simple plantilla hash_key < T> si no hay una especialización disponible. No requieren que especialices el contenedor completo.

Aunque el ejemplo es lo suficientemente simple para simplemente especializarse toda la función, en general, me gustaría poner en práctica Func < T> genérica y especializado DoSomethingSpecial < T>, así:

template< class T > 
void DoSomethingSpecial(T &input) 
{ 
... 
} 

template< class T > 
void Func(T input) 
{ 
DoSomethingGeneral1(); 
... 
DoSomethingSpecial(T); 
... 
DoSomethingGeneral2(); 
} 

template<> 
void DoSomethingSpecial(std::string &input) 
{ 
... 
} 

template<> 
void DoSomethingSpecial(int &input) 
{ 
... 
} 
+0

lo consideraré, gracias. –

Cuestiones relacionadas