Der Typ std::any
kann ab C++17 Objekte jedes beliebigen Typs aufnehmen und wird damit ein typsicherer Ersatz für void*
.
Das verwaltete Objekt wird bei Zuweisung eines anderen Objektes zerstört, spätestens jedoch mit der Kapsel:
std::any o; // empty o = 1; o = 3.14; o = "hello world";
Entpacken erfordert die Kenntnis der möglicherweise enthaltenen Typen.
Ein erfolgreicher std::any_cast<ZielTyp>
auf die Adresse der Kapsel liefert einen gültigen Zeiger des Zieltyps:
if (auto ptr = std::any_cast<int>(&o)) std::cout << *ptr << '\n'; if (auto ptr = std::any_cast<double>(&o)) std::cout << *ptr << '\n'; if (auto ptr = std::any_cast<const char*>(&o)) std::cout << *ptr << '\n';
Wird die Kapsel selbst gecastet, erhält man bei passendem Typ Zugriff auf das enthaltene Objekt. Andernfalls wird eine Ausnahme geworfen:
try { std::cout << std::any_cast<int>(o) << '\n'; } catch(std::bad_any_cast& err) { std::cerr << err.what() << '\n'; }
Das enthaltene Objekt lässt sich bei Bedarf löschen:
if (o.has_value()) o.reset();
Das Objekt lässt sich direkt im Wrapper aus übergebenen Konstruktorparametern zusammensetzen:
std::any a(std::in_place_type<std::string>, 10, '-'); a.emplace<std::string>(10, '-'); std::cout << std::any_cast<std::string>(a);