Generics en C++: para qué sirven y cómo usarlos en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: qué son los generics en C++ y para qué sirven

En el mundo de la programación moderna, la reutilización del código es uno de los principios clave. Si escribes una función de suma para int, y luego para double y float, tarde o temprano querrás evitar la duplicación. Aquí es donde los generics (programación genérica) vienen al rescate. En C++, este concepto se implementa a través de plantillas (templates).

Los generics permiten escribir código que funciona con cualquier tipo de datos, sin sacrificar el rendimiento (a diferencia de las funciones virtuales o void*). El compilador genera una versión separada de la función o clase para cada tipo específico, lo que proporciona la máxima velocidad de ejecución.

En este artículo, analizaremos para qué sirven los generics en C++, cómo declararlos y usarlos correctamente en la práctica, así como los errores típicos y las técnicas avanzadas.



Fundamentos de sintaxis: cómo declarar y usar una plantilla

Una plantilla en C++ se declara con la palabra clave template y los corchetes angulares <>, dentro de los cuales se especifica el parámetro de tipo (generalmente typename o class).

Función plantilla

El ejemplo más simple es una función que devuelve el máximo de dos valores:

template <typename T>T max(T a, T b) {    return (a > b) ? a : b;}

// Uso:int main() { std::cout << max(3, 7) << std::endl; // 7 std::cout << max(3.14, 2.71) << std::endl; // 3.14 std::cout << max('a', 'z') << std::endl; // z return 0;}

Observa: el compilador deduce el tipo T automáticamente según los argumentos pasados. Si necesitas especificar el tipo explícitamente, puedes escribir max<double>(3.14, 2.71).



Clase plantilla

Las plantillas también funcionan con clases. Un ejemplo clásico es un contenedor simple "par":

template <typename T1, typename T2>class Pair {private:    T1 first;    T2 second;public:    Pair(T1 f, T2 s) : first(f), second(s) {}    T1 getFirst() const { return first; }    T2 getSecond() const { return second; }};

// Uso:Pair<int, std::string> student(1, "Alice");std::cout << student.getFirst() << " " << student.getSecond();

Aquí T1 y T2 son parámetros de plantilla que pueden ser cualquier tipo.



Ejemplos prácticos: desde contenedores simples hasta algoritmos

Veamos varios escenarios reales donde los generics son indispensables.



Ordenamiento universal

Escribamos una función plantilla para ordenar un arreglo de cualquier tipo que soporte el operador <:

template <typename T>void bubbleSort(T arr[], int n) {    for (int i = 0; i < n - 1; ++i)        for (int j = 0; j < n - i - 1; ++j)            if (arr[j] > arr[j + 1])                std::swap(arr[j], arr[j + 1]);}

// Ejemplo:int intArr[] = {5, 2, 8, 1};bubbleSort(intArr, 4); // Funciona con int

double dblArr[] = {3.14, 2.71, 1.41};bubbleSort(dblArr, 3); // Funciona con double


Pila con tipo de datos arbitrario

Implementemos una pila simple basada en plantillas:

template <typename T>class Stack {private:    std::vector<T> elements;public:    void push(const T& value) { elements.push_back(value); }    void pop() { if (!elements.empty()) elements.pop_back(); }    T top() const { return elements.back(); }    bool empty() const { return elements.empty(); }};

// Uso:Stack<int> intStack;intStack.push(10);intStack.push(20);std::cout << intStack.top(); // 20


Algoritmo "buscar y reemplazar"

Función plantilla que reemplaza todas las ocurrencias de un valor por otro en un contenedor:

templa                

Blogs

Book Recommendations