std::tuple în C++

Grupează oricâte valori de tipuri diferite într-un singur obiect; generalizarea lui std::pair.

Sintaxă
#include <tuple>

std::tuple<T1, T2, T3> t{v1, v2, v3};
auto t = std::make_tuple(v1, v2, v3);

Ce face std::tuple

std::tuple ține un număr fix de valori, fiecare cu tipul ei: de exemplu un nume, o vârstă și o medie. Elementele nu au nume, ci poziții: le citești cu std::get<0>(t), std::get<1>(t) sau le despachetezi cu auto [a, b, c] = t;.

std::make_tuple(...) creează un tuplu și deduce tipurile; din C++17 poți scrie și std::tuple{...}. Tuplurile se compară lexicografic (primul element, apoi al doilea…), ceea ce le face utile pentru sortări după mai multe criterii.

Pentru date folosite des în program, o struct cu câmpuri cu nume este mai clară. Tuplul este potrivit pentru valori returnate rapid dintr-o funcție sau pentru cod generic.

Parametri

Parametru Descriere
T1, T2, ... Tipurile elementelor.
v1, v2, ... Valorile inițiale.

Ce returnează

std::make_tuple returnează un std::tuple cu tipurile deduse.

Exemple

Exemplul 1: Creare, acces și afișare

#include <print>
#include <string>
#include <tuple>

int main() {
    std::tuple<std::string, int, double> elev{"Maria", 17, 9.45};
    auto produs = std::make_tuple("laptop", 3, 3499.99);

    std::println("{} are {} ani și media {}", std::get<0>(elev), std::get<1>(elev), std::get<2>(elev));
    std::println("{}", produs);

    auto [nume, bucati, pret] = produs;
    std::println("{} x {} = {:.2f} lei", bucati, nume, bucati * pret);
}

Rezultat

Maria are 17 ani și media 9.45
("laptop", 3, 3499.99)
3 x laptop = 10499.97 lei

Exemplul 2: Returnarea a trei valori

#include <print>
#include <tuple>
#include <vector>

std::tuple<int, int, double> statistici(const std::vector<int>& note) {
    int suma = 0;
    int peste_5 = 0;
    for (int n : note) {
        suma += n;
        if (n >= 5) ++peste_5;
    }
    return {static_cast<int>(note.size()), peste_5, static_cast<double>(suma) / static_cast<double>(note.size())};
}

int main() {
    auto [total, promovati, medie] = statistici({4, 9, 7, 10, 3});
    std::println("{} elevi, {} promovați, media {:.2f}", total, promovati, medie);
}

Rezultat

5 elevi, 3 promovați, media 6.60

Greșeli frecvente

  • Încerci std::get<i>(t) cu o variabilă i. Indicele trebuie să fie o constantă cunoscută la compilare; un tuplu nu se parcurge cu o buclă obișnuită (folosește std::apply).
  • Folosești std::make_tuple cu referințe și te aștepți ca tuplul să le păstreze: make_tuple copiază valorile. Pentru referințe, folosește std::tie sau std::ref.

Comenzi înrudite

  • std::pair: Grupează două valori, eventual de tipuri diferite, într-un singur obiect cu membrii first și second.
  • std::get: Citește elementul unui tuplu, al unei perechi sau al unui std::array după poziție (sau după tip), la compilare.
  • std::tie: Creează un tuplu de referințe la variabile existente: despachetează un tuplu în ele sau compară mai multe câmpuri deodată.
  • std::apply: Apelează o funcție dând ca argumente, pe rând, elementele unui tuplu (sau ale unei perechi, ale unui std::array).
  • std::tuple_size: Dă, la compilare, numărul de elemente dintr-un tip tuple, pair sau std::array.