Ce face std::optional
std::optional<T> este răspunsul modern la întrebarea „ce returnez când nu am rezultat?”. În loc de valori speciale (-1, șir gol, nullptr), funcția returnează un optional gol, iar apelantul trebuie să verifice.
Verificarea se face cu o.has_value() sau direct în if (o). Valoarea se citește cu *o (fără verificare), o.value() (aruncă excepție dacă e gol) sau o.value_or(implicit). std::nullopt este constanta care înseamnă „gol”.
std::make_optional(x) creează un optional cu tipul dedus din x. Obiectul este stocat direct în optional, fără alocare dinamică.
Ce returnează
Un obiect care fie conține o valoare de tip T, fie este gol. has_value() returnează bool.
Exemple
Exemplul 1: Căutare care poate să nu găsească nimic
#include <optional>
#include <print>
#include <string>
#include <vector>
std::optional<int> pozitie(const std::vector<std::string>& v, const std::string& cautat) {
for (int i = 0; i < static_cast<int>(v.size()); ++i) {
if (v[i] == cautat) {
return i;
}
}
return std::nullopt;
}
int main() {
std::vector<std::string> orase{"Iași", "Cluj", "Brașov"};
if (auto p = pozitie(orase, "Cluj")) {
std::println("Cluj este pe poziția {}", *p);
}
auto q = pozitie(orase, "Arad");
std::println("Arad găsit: {}", q.has_value());
}
Rezultat
Cluj este pe poziția 1
Arad găsit: false
Exemplul 2: Câmpuri opționale, nullopt și make_optional
#include <optional>
#include <print>
#include <string>
struct Persoana {
std::string nume;
std::optional<std::string> telefon;
};
void afiseaza(const Persoana& p) {
std::println("{}: {}", p.nume, p.telefon ? *p.telefon : "fără telefon");
}
int main() {
Persoana ana{"Ana", "0742 000 000"};
Persoana ion{"Ion", std::nullopt};
afiseaza(ana);
afiseaza(ion);
auto varsta = std::make_optional(25); // std::optional<int>
varsta = std::nullopt;
std::println("are vârstă: {}", varsta.has_value());
}
Rezultat
Ana: 0742 000 000
Ion: fără telefon
are vârstă: false
Greșeli frecvente
- Citești
*ofără să verifici căoare valoare. Pe unoptionalgol,*oeste comportament nedefinit; foloseșteif (o),value()sauvalue_or. - Scrii
std::optional<T&>. Nu există (până în C++26); folosește un pointer saustd::optional<std::reference_wrapper<T>>. - Pentru
std::optional<bool>,if (o)verifică dacă există valoare, nu dacă valoarea estetrue. Scrieif (o && *o)sauo.value_or(false).
Comenzi înrudite
std::optional::value: value() citește valoarea și aruncă excepție dacă optional e gol; value_or() dă o valoare implicită.std::optional::and_then: Înlănțuiește operații pe un optional: and_then și transform rulează funcția doar dacă există valoare.std::expected: Rezultatul unei operații care poate eșua: conține fie valoarea (T), fie motivul erorii (E).std::variant: O valoare care are, la un moment dat, exact unul dintre mai multe tipuri posibile (union sigur).