ProgramaciónDesarrollador C++

¿Qué son las plantillas (templates) en C++? ¿Qué tipos de plantillas existen? ¿Qué dificultades y errores surgen al diseñar y utilizar plantillas? Muestre un ejemplo de plantilla de clase y de función.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Las plantillas (templates) son un mecanismo de C++ que permite crear clases y funciones genéricas que funcionan con diferentes tipos de datos sin duplicar código. Esta es la base de la implementación de contenedores STL, algoritmos y muchos patrones de programación genérica.

Tipos de plantillas:

  • Plantillas de funciones: permiten crear una función para diferentes tipos.
  • Plantillas de clases: permiten crear clases que operan con diferentes tipos.
  • Plantillas con parámetros de valores: no solo se pueden parametrizar por tipos, sino también por valores constantes.

Ejemplo de plantilla de clase:

template<typename T> class Box { public: Box(T value): data(value) {} T get() const { return data; } private: T data; };

Ejemplo de plantilla de función:

template<class T> T add(const T& a, const T& b) { return a + b; }

Pregunta capciosa.

¿Se puede especializar explícitamente solo un método de una clase de plantilla, sin especializar toda la clase? Si es así, ¿cómo se hace?

Respuesta:
Sí, se puede. No es necesario especializar toda la clase; se puede simplemente especializar un método individual:

template <typename T> class Foo { public: void bar(); }; template <> void Foo<int>::bar() { // Especialización solo del método bar para int // Implementación }

Ejemplos de errores reales debido al desconocimiento de los matices del tema.


Historia
En el proyecto se escribió una plantilla de función para comparación:

template <typename T> bool cmp(const T& a, const T& b) { return a < b; }

Al usarla con tipos que no tienen el operador <, se produjo un error de compilación que se buscó durante mucho tiempo, ya que el diagnóstico se daba solo al instanciar la plantilla, y no en el lugar de su definición.


Historia
Un desarrollador intentó usar la suma en una función de plantilla para una clase de usuario, olvidando sobrecargar el operador +. Esto resultó en errores de compilación en la primera llamada con esa clase.


Historia
Al desarrollar un contenedor basado en una plantilla de clase, se creó un método que no dependía del tipo de la plantilla, pero fue colocado fuera de la clase sin una especialización explícita:

template<> int MyContainer<int>::size() const { ... }

Esto resultó en un error de enlace porque la especialización se declaró, pero no se implementó correctamente para todos los tipos.