cpp-que-son-tuplas

Qué son y cómo usar las tuplas en C++

En C++ una tupla es una estructura de datos que permite agrupar múltiples valores de diferentes tipos en una sola variable.

A diferencia de las clases o estructuras (struct), las tuplas son más simples y están diseñadas para manejar conjuntos de datos de diferentes tipos sin necesidad de definir una nuevo tipo.

Las tuplas en C++ son inmutables, lo que significa que, una vez creadas, sus valores no pueden ser modificados. Esta característica las hace ideales para representar agrupaciones de datos que no necesitan cambiar una vez definidas.

Sintaxis de las Tuplas

Las tuplas se definen y utilizan a través de la clase std::tuple del estándar de la biblioteca C++.

#include <tuple>

std::tuple<tipo1, tipo2> tupla = std::make_tuple(valor1, valor2);

Donde:

  • tipo1, tipo2: Son los tipos de datos de los elementos de la tupla.
  • valor1, valor2: Son los valores que se asignan a los elementos de la tupla.

Es posible crear una tupla con cualquier número de elementos (aunque no es recomendable hacer tuplas extremadamente largas para mantener la claridad del código)

#include <tuple>

std::tuple<int, std::string, double> miTupla = std::make_tuple(1, "Hola", 3.14);

Ejemplo Básico

Veamos un ejemplo sencillo para definir y utilizar una tupla en C++:

#include <iostream>
#include <tuple>

int main() {
    std::tuple<int, std::string, double> miTupla = std::make_tuple(1, "Hola", 3.14);

    // Acceso a los elementos
    int entero = std::get<0>(miTupla);
    std::string texto = std::get<1>(miTupla);
    double numero = std::get<2>(miTupla);

    std::cout << "Entero: " << entero << std::endl; // Imprime "Entero: 1"
    std::cout << "Texto: " << texto << std::endl;   // Imprime "Texto: Hola"
    std::cout << "Número: " << numero << std::endl; // Imprime "Número: 3.14"

    return 0;
}

Uso Básico

Acceso a los Elementos de la Tupla

Para acceder a los elementos de una tupla, se utiliza la función std::get<N>(tupla), donde N es el índice del elemento que queremos obtener (empezando desde 0).

std::tuple<int, std::string, bool> tupla = std::make_tuple(1, "Hola", true);

int numero = std::get<0>(tupla);   // Obtiene el primer elemento
std::string texto = std::get<1>(tupla); // Obtiene el segundo elemento
bool valorBooleano = std::get<2>(tupla); // Obtiene el tercer elemento

Destructuración de Tuplas

Aunque C++ no tiene destructuración directa para tuplas como otros lenguajes, puedes utilizar std::tie para descomponer una tupla en variables separadas.

#include <iostream>
#include <tuple>

int main() {
    std::tuple<int, std::string, double> tupla = std::make_tuple(1, "Hola", 3.14);

    int entero;
    std::string texto;
    double numero;

    std::tie(entero, texto, numero) = tupla;

    std::cout << "Entero: " << entero << std::endl;
    std::cout << "Texto: " << texto << std::endl;
    std::cout << "Número: " << numero << std::endl;

    return 0;
}

Ejemplos Prácticos

Método que Retorna una Tupla

Un uso común de las tuplas es retornar múltiples valores desde una función:

#include <iostream>
#include <tuple>

// Método que calcula la suma y el producto de dos números
std::tuple<int, int> Calcular(int a, int b) {
    int suma = a + b;
    int producto = a * b;
    return std::make_tuple(suma, producto);
}

int main() {
    auto [suma, producto] = Calcular(3, 4);

    std::cout << "Suma: " << suma << std::endl;       // Imprime "Suma: 7"
    std::cout << "Producto: " << producto << std::endl; // Imprime "Producto: 12"

    return 0;
}

Tuplas como Parámetros de Métodos

Las tuplas también pueden ser usadas como parámetros en métodos:

#include <iostream>
#include <tuple>

// Método que muestra información de una persona usando una tupla como parámetro
void MostrarInformacion(const std::tuple<std::string, int>& persona) {
    std::string nombre;
    int edad;
    std::tie(nombre, edad) = persona;

    std::cout << "Nombre: " << nombre << std::endl;
    std::cout << "Edad: " << edad << std::endl;
}

int main() {
    std::tuple<std::string, int> persona = std::make_tuple("Juan", 30);
    MostrarInformacion(persona);

    return 0;
}

Comparación de Tuplas

Las tuplas en C++ pueden compararse directamente usando los operadores de comparación:

#include <iostream>
#include <tuple>

int main() {
    std::tuple<int, std::string> tupla1 = std::make_tuple(1, "Hola");
    std::tuple<int, std::string> tupla2 = std::make_tuple(1, "Hola");
    std::tuple<int, std::string> tupla3 = std::make_tuple(2, "Adiós");

    bool sonIguales = (tupla1 == tupla2); // true
    bool sonDiferentes = (tupla1 != tupla3); // true

    std::cout << "tupla1 == tupla2: " << sonIguales << std::endl; // Imprime 1
    std::cout << "tupla1 != tupla3: " << sonDiferentes << std::endl; // Imprime 1

    return 0;
}

Uso de Tuplas en Consultas LINQ

Aunque C++ no tiene LINQ, puedes usar tuplas en contextos similares para manejar y filtrar datos:

#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>

// Crear una lista de tuplas que representan personas
std::vector<std::tuple<std::string, int>> personas = {
    std::make_tuple("Juan", 25),
    std::make_tuple("María", 30),
    std::make_tuple("Pedro", 28)
};

int main() {
    // Filtrar y seleccionar personas mayores de 25 años
    std::vector<std::tuple<std::string, int>> mayoresDe25;

    std::copy_if(personas.begin(), personas.end(), std::back_inserter(mayoresDe25),
        [](const std::tuple<std::string, int>& persona) {
            return std::get<1>(persona) > 25;
        });

    // Imprimir las personas filtradas
    for (const auto& persona : mayoresDe25) {
        std::cout << "Nombre: " << std::get<0>(persona) << ", Edad: " << std::get<1>(persona) << std::endl;
    }

    return 0;
}

Uso de Tuplas como Clave de un Diccionario

Finalmente, las tuplas pueden usarse como claves en un diccionario (std::map) dado que son inmutables:

#include <iostream>
#include <map>
#include <tuple>

int main() {
    // Crear un diccionario con tuplas como claves y strings como valores
    std::map<std::tuple<std::string, int>, std::string> empleados;

    // Añadir elementos al diccionario
    empleados[std::make_tuple("Ventas", 101)] = "Juan Pérez";
    empleados[std::make_tuple("Marketing", 102)] = "María López";
    empleados[std::make_tuple("TI", 103)] = "Pedro González";

    // Buscar empleados en el diccionario usando tuplas como claves
    std::string empleadoVentas = empleados[std::make_tuple("Ventas", 101)];
    std::string

 empleadoMarketing = empleados[std::make_tuple("Marketing", 102)];

    std::cout << "Empleado en Ventas con ID 101: " << empleadoVentas << std::endl;
    std::cout << "Empleado en Marketing con ID 102: " << empleadoMarketing << std::endl;

    return 0;
}