Dominando Plantillas en C++: Guía de Programación Genérica
Las plantillas son la base de la programación genérica, que implica escribir código de una manera que es independiente de cualquier tipo particular.
Una plantilla es un modelo o fórmula para crear una clase genérica o una función. Los contenedores de biblioteca como iteradores y algoritmos son ejemplos de programación genérica y han sido desarrollados usando el concepto de plantilla.
Hay una sola definición de cada contenedor, como vector, pero podemos definir muchos tipos diferentes de vectores, por ejemplo, vector<int> o vector<string>.
Puedes usar plantillas para definir funciones así como clases, veamos cómo funcionan:
Plantilla de Función
La forma general de una definición de función plantilla se muestra aquí:
template <class tipo> tipo-retorno nombre-func(lista-parámetros) {
// cuerpo de la función
}
Aquí, tipo es un nombre de marcador de posición para un tipo de dato usado por la función. Este nombre puede usarse dentro de la definición de la función.
El siguiente es el ejemplo de una función plantilla que retorna el máximo de dos valores:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max(T const& a, T const& b) {
return a < b ? b : a;
}
int main() {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hola";
string s2 = "Mundo";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): Mundo
Plantilla de Clase
Así como podemos definir plantillas de función, también podemos definir plantillas de clase. La forma general de una declaración de clase genérica se muestra aquí:
template <class tipo> class nombre-clase {
...
}
Aquí, tipo es el nombre del tipo de marcador de posición, que será especificado cuando una clase sea instanciada. Puedes definir más de un tipo de dato genérico usando una lista separada por comas.
El siguiente es el ejemplo para definir la clase Stack<> e implementar métodos genéricos para apilar y desapilar elementos de la pila:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Pila {
private:
vector<T> elementos; // elementos
public:
void push(T const&); // apilar elemento
void pop(); // desapilar elemento
T top() const; // retornar elemento superior
bool empty() const { // retornar true si vacía
return elementos.empty();
}
};
template <class T>
void Pila<T>::push(T const& elem) {
// agregar copia del elemento pasado
elementos.push_back(elem);
}
template <class T>
void Pila<T>::pop() {
if(elementos.empty()) {
throw out_of_range("Pila<>::pop(): pila vacía");
}
// eliminar último elemento
elementos.pop_back();
}
template <class T>
T Pila<T>::top() const {
if(elementos.empty()) {
throw out_of_range("Pila<>::top(): pila vacía");
}
// retornar copia del último elemento
return elementos.back();
}
int main() {
try {
Pila<int> pilaInt; // pila de ints
Pila<string> pilaString; // pila de strings
// manipular pila int
pilaInt.push(7);
cout << pilaInt.top() << endl;
// manipular pila string
pilaString.push("hola");
cout << pilaString.top() << std::endl;
pilaString.pop();
pilaString.pop();
} catch(exception const& ex) {
cerr << "Excepción: " << ex.what() << endl;
return -1;
}
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
7
hola
Excepción: Pila<>::pop(): pila vacía
Lenguaje C
- Entendiendo los Tipos de Datos en C++: Fundamentos, Modificadores y Mejores Prácticas
- Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
- Comentarios en C++: Mejores Prácticas para Código Legible y Mantenible
- Entendiendo los Constructores en C++: Por Defecto, Parametrizados y de Copia Explicados
- Dominando las plantillas de clase en C++: guía práctica
- Lenguaje de Programación C++: Visión General y Características Clave
- Constantes y Literales en C++: Tipos, Sintaxis y Mejores Prácticas
- Guía Completa de Operadores en C++: Tipos, Uso y Mejores Prácticas
- Dominando los Tipos Numéricos en C++: Guía Práctica
- Entendiendo las Referencias en C++: Conceptos Clave y Diferencias con Punteros
- Preprocesador de C++: Cómo las Directivas Moldean tu Código