Menu
Coddy logo textTech

Plantillas variádicas

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 67 de 104.

¿Qué ocurre si necesitas una función que acepte cualquier número de argumentos de cualquier tipo? Las plantillas tradicionales requieren que especifiques exactamente cuántos parámetros de tipo necesitas. Las plantillas variádicas resuelven esto al permitir que las plantillas acepten un número arbitrario de argumentos de plantilla.

La sintaxis utiliza ... (puntos suspensivos) para crear un paquete de parámetros:

template <typename... Args>
void printAll(Args... args) {
    // Args es un paquete de parámetros de plantilla
    // args es un paquete de parámetros de función
}

Para procesar los argumentos, normalmente usas recursión con un caso base. El paquete de parámetros se expande argumento por argumento hasta que no queda ninguno:

// Caso base: no quedan argumentos
void print() {
    std::cout << std::endl;
}

// Caso recursivo: procesa el primer argumento, recurre con el resto
template <typename T, typename... Rest>
void print(T first, Rest... rest) {
    std::cout << first << " ";
    print(rest...);  // Expande los argumentos restantes
}

print(1, 3.14, "hello", 'x');  // Salida: 1 3.14 hello x

También puedes usar expresiones fold (C++17) para realizar operaciones más sencillas sin recursión explícita:

template <typename... Args>
auto sum(Args... args) {
    return (args + ...);  // Expresión fold: suma todos los argumentos
}

std::cout << sum(1, 2, 3, 4) << std::endl;  // Salida: 10

Las plantillas variádicas impulsan muchas funciones de la biblioteca estándar, como std::make_unique, std::tuple y std::function. Permiten crear funciones con seguridad de tipos que funcionan con cualquier combinación de tipos y cantidades de argumentos.

challenge icon

Desafío

Fácil

Construyamos un sistema de registro flexible que use plantillas variádicas para gestionar mensajes con cualquier número de argumentos. Crearás utilidades que puedan concatenar valores, contar argumentos e imprimir resultados con formato: todo usando paquetes de parámetros.

Organizarás tu código en dos archivos:

  • Variadic.h: Define aquí tus funciones de plantilla variádicas.

    Crea una función printAll que imprima todos sus argumentos separados por espacios, seguidos de un salto de línea. Usa el enfoque recursivo con un caso base que imprima solo un salto de línea y un caso recursivo que imprima el primer argumento, un espacio y después se llame recursivamente con los argumentos restantes.

    Crea una función countArgs que devuelva el número de argumentos que se le pasaron. Usa sizeof... para obtener el tamaño del paquete de parámetros.

    Crea una función sum que sume todos los argumentos numéricos y devuelva el resultado. Usa una expresión de plegado con el operador +.

    Crea una función product que multiplique todos los argumentos numéricos y devuelva el resultado. Usa una expresión de plegado con el operador *.

  • main.cpp: Lee cuatro entradas (cada una en una línea separada):
    1. Un entero
    2. Un double
    3. Una cadena
    4. Un carácter

    Demuestra tus plantillas variádicas haciendo lo siguiente:

    1. Llamar a printAll con las cuatro entradas e imprimir el resultado
    2. Imprimir el conteo de argumentos al llamar a countArgs con el entero, el double y el carácter: Argument count: <count>
    3. Calcular la suma del entero, el double y los valores 10 y 5; después, imprimir: Sum: <result>
    4. Calcular el producto del entero y los valores 2 y 3; después, imprimir: Product: <result>
    5. Llamar a printAll solo con la cadena (un único argumento)
    6. Llamar a printAll sin argumentos (debe imprimir solo un salto de línea)

Por ejemplo, con las entradas 5, 2.5, Hello y X:

5 2.5 Hello X 
Argument count: 3
Sum: 22.5
Product: 30
Hello 

Observa cómo printAll gestiona cualquier número de argumentos de tipos mixtos, desde cuatro argumentos hasta cero. Las funciones sum y product usan expresiones de plegado para combinar elegantemente todos los valores sin recursión explícita. Tu función countArgs demuestra cómo sizeof... proporciona el tamaño del paquete en tiempo de compilación.

Pruébalo tú mismo

#include <iostream>
#include <string>
#include "Variadic.h"

using namespace std;

int main() {
    // Leer entradas
    int intVal;
    double doubleVal;
    string strVal;
    char charVal;
    
    cin >> intVal;
    cin >> doubleVal;
    cin >> strVal;
    cin >> charVal;
    
    // TODO: Llama a printAll con las cuatro entradas
    
    // TODO: Print argument count using countArgs with intVal, doubleVal, and charVal
    // Format: "Argument count: <count>"
    
    // TODO: Calcula e imprime la suma de intVal, doubleVal, 10 y 5
    // Formato: "Sum: <result>"
    
    // TODO: Calcula e imprime el producto de intVal, 2 y 3
    // Formato: "Product: <result>"
    
    // TODO: Llama a printAll solo con el string
    
    // TODO: Llama a printAll sin argumentos
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C++ online