std::any în C++

Container pentru o singură valoare de orice tip; std::any_cast o scoate înapoi cu tipul corect.

Sintaxă
#include <any>
std::any a = valoare;
template<class T> T any_cast(const std::any& a);
template<class T> const T* any_cast(const std::any* a) noexcept;

Ce face std::any

std::any poate ține o valoare de orice tip care se poate copia, iar tipul se poate schimba la fiecare atribuire. Spre deosebire de std::variant, lista de tipuri nu este cunoscută dinainte.

Valoarea se citește cu std::any_cast<T>(a): dacă tipul nu este exact T, se aruncă std::bad_any_cast. Varianta cu pointer, std::any_cast<T>(&a), returnează nullptr în loc să arunce. a.has_value() spune dacă există o valoare, iar a.type() returnează tipul ei.

Folosește-l rar. Dacă știi tipurile posibile, std::variant este mai sigur și mai rapid.

Ce returnează

any_cast<T> returnează valoarea de tip T (sau un pointer la ea, în varianta cu pointer).

Exemple

Exemplul 1: Setări de tipuri diferite

#include <any>
#include <map>
#include <print>
#include <string>

int main() {
    std::map<std::string, std::any> setari;
    setari["port"] = 8080;
    setari["gazda"] = std::string("dexblog.ro");
    setari["debug"] = true;

    std::println("port: {}", std::any_cast<int>(setari["port"]));
    std::println("gazda: {}", std::any_cast<std::string>(setari["gazda"]));

    if (auto* d = std::any_cast<bool>(&setari["debug"])) {
        std::println("debug: {}", *d);
    }
}

Rezultat

port: 8080
gazda: dexblog.ro
debug: true

Exemplul 2: Tip greșit: bad_any_cast

Valoarea este int, nu double. any_cast nu face conversii.

#include <any>
#include <print>

int main() {
    std::any a = 5;
    try {
        std::println("{}", std::any_cast<double>(a));
    } catch (const std::bad_any_cast& e) {
        std::println("Eroare: {}", e.what());
    }
    a.reset();
    std::println("are valoare: {}", a.has_value());
}

Rezultat

Eroare: bad any cast
are valoare: false

Greșeli frecvente

  • Pui în any un literal de text (a = "Ana";) și citești cu any_cast<std::string>. Tipul stocat este const char*, deci se aruncă bad_any_cast.

Comenzi înrudite

  • std::variant: O valoare care are, la un moment dat, exact unul dintre mai multe tipuri posibile (union sigur).
  • std::optional: O valoare care poate lipsi: conține fie un obiect de tip T, fie nimic (std::nullopt).
  • typeid: Dă informații despre tipul unei expresii la rulare; pentru clase cu funcții virtuale arată tipul real al obiectului.