Ce face std::variant
std::variant<int, double, std::string> poate ține fie un int, fie un double, fie un std::string. Știe mereu ce tip conține acum, deci, spre deosebire de union, nu poți citi din greșeală tipul greșit fără să afli.
v.index() returnează poziția tipului curent în listă (0, 1, 2…). Valoarea se citește cu std::get<T>(v) (aruncă std::bad_variant_access dacă tipul nu se potrivește), cu std::get_if sau, cel mai elegant, cu std::visit.
Un variant neinițializat explicit conține o valoare implicită a primului tip.
Ce returnează
Un obiect care conține o valoare de unul dintre tipurile enumerate.
Exemple
Exemplul 1: Același variant, tipuri diferite
#include <print>
#include <string>
#include <variant>
int main() {
std::variant<int, double, std::string> v;
std::println("index: {} (int implicit: {})", v.index(), std::get<int>(v));
v = 3.14;
std::println("index: {} -> {}", v.index(), std::get<double>(v));
v = std::string("Timișoara");
std::println("index: {} -> {}", v.index(), std::get<std::string>(v));
}
Rezultat
index: 0 (int implicit: 0)
index: 1 -> 3.14
index: 2 -> Timișoara
Exemplul 2: Tipul greșit aruncă excepție
#include <print>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> rezultat = "eroare de rețea";
try {
std::println("{}", std::get<int>(rezultat));
} catch (const std::bad_variant_access& e) {
std::println("Nu conține int: {}", e.what());
}
}
Rezultat
Nu conține int: bad_variant_access
Greșeli frecvente
- Scrii
std::variant<std::string, bool> v = "text";. Înainte de C++20 un literal de tipconst char*se transforma înbool; regula a fost corectată, dar e mai sigur să scriistd::string("text"). - Folosești
v.index()cu numere scrise de mână în tot codul. Dacă schimbi ordinea tipurilor, numerele devin greșite; preferăstd::visitsaustd::holds_alternative.
Comenzi înrudite
std::visit: Apelează o funcție cu valoarea curentă dintr-un std::variant, oricare ar fi tipul ei.std::holds_alternative: holds_alternative verifică ce tip are acum un variant; get_if returnează pointer la valoare sau nullptr.std::optional: O valoare care poate lipsi: conține fie un obiect de tip T, fie nimic (std::nullopt).std::any: Container pentru o singură valoare de orice tip; std::any_cast o scoate înapoi cu tipul corect.union: Un tip în care toți membrii împart aceeași zonă de memorie; la un moment dat doar unul dintre ei are o valoare validă.