std::tie în C++

Creează un tuplu de referințe la variabile existente: despachetează un tuplu în ele sau compară mai multe câmpuri deodată.

Sintaxă
template<class... Types>
std::tuple<Types&...> tie(Types&... argumente) noexcept;

Ce face std::tie

std::tie(a, b, c) returnează un tuplu ale cărui elemente sunt referințe la a, b, c. Dacă îi atribui un tuplu (std::tie(a, b) = f();), valorile ajung direct în variabilele existente. std::ignore ține locul unei valori care nu te interesează.

A doua utilizare frecventă este compararea pe mai multe criterii: std::tie(a.nume, a.varsta) < std::tie(b.nume, b.varsta) compară întâi numele, apoi vârsta. Pentru variabile noi, despachetarea modernă auto [a, b] = ...; (C++17) este de obicei mai simplă.

Parametri

Parametru Descriere
argumente Variabilele (lvalue) legate în tuplu.

Ce returnează

Un std::tuple de referințe.

Exemple

Exemplul 1: Despachetare în variabile existente

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

std::tuple<std::string, int, bool> citeste_utilizator() {
    return {"ana.pop", 34, true};
}

int main() {
    std::string nume;
    bool activ = false;
    std::tie(nume, std::ignore, activ) = citeste_utilizator();   // vârsta nu ne interesează
    std::println("{} activ={}", nume, activ);

    int a = 1;
    int b = 2;
    std::tie(a, b) = std::tuple{b, a};    // schimbare de valori
    std::println("a={} b={}", a, b);
}

Rezultat

ana.pop activ=true
a=2 b=1

Exemplul 2: Comparare după mai multe câmpuri

#include <algorithm>
#include <print>
#include <string>
#include <tuple>
#include <vector>

struct Elev {
    std::string clasa;
    double medie;
    std::string nume;
};

int main() {
    std::vector<Elev> elevi{{"9B", 9.1, "Ion"}, {"9A", 8.7, "Ana"}, {"9B", 9.8, "Eva"}, {"9A", 9.5, "Dan"}};
    std::sort(elevi.begin(), elevi.end(), [](const Elev& x, const Elev& y) {
        // clasa crescător, apoi media descrescător (de aceea y și x sunt inversate la medie)
        return std::tie(x.clasa, y.medie) < std::tie(y.clasa, x.medie);
    });
    for (const auto& e : elevi) {
        std::println("{} {} {}", e.clasa, e.medie, e.nume);
    }
}

Rezultat

9A 9.5 Dan
9A 8.7 Ana
9B 9.8 Eva
9B 9.1 Ion

Greșeli frecvente

  • Dai lui std::tie valori temporare (std::tie(f(), 3)): nu compilează, pentru că are nevoie de variabile. Pentru valori, folosește std::make_tuple.
  • Returnezi dintr-o funcție std::tie(variabila_locala): referințele indică variabile distruse la ieșirea din funcție.

Comenzi înrudite

  • std::tuple: Grupează oricâte valori de tipuri diferite într-un singur obiect; generalizarea lui std::pair.
  • std::get: Citește elementul unui tuplu, al unei perechi sau al unui std::array după poziție (sau după tip), la compilare.
  • std::pair: Grupează două valori, eventual de tipuri diferite, într-un singur obiect cu membrii first și second.
  • structured bindings (auto [a, b]): Desface o pereche, un tuplu, o structură sau un tablou în variabile separate, cu nume, într-o singură declarație.