Klasa std::any¶
std::any
umożliwia:
- bezpieczne (typowane) mechanizmy przechowywania i odwoływania się do wartości dowolnych typów
- bezpiecznie typizowany odpowiednik
void*
- bezpiecznie typizowany odpowiednik
- przechowywanie elementów heterogenicznych w kontenerach biblioteki standardowej
- przekazywanie wartości dowolnych typów pomiędzy warstwami, bez konieczności wyposażania warstw pośredniczących w jakąkolwiek wiedzę o tych typach
Klasa std::any
służy do przechowywania i udostępniania wartości dowolnych typów, ale pod warunkiem znajomości tych typów, a więc z zachowaniem zalet i bezpieczeństwa typowania.
Typy przechowywane w std::any
muszą spełniać następujące warunki:
- muszą umożliwiać kopiowanie - typy move-only nie są wspierane, choć klasa
- muszą umożliwiać przypisywanie (publiczny operator przypisania)
- nie mogą rzucać wyjątków z destruktora (to jest wymóg odnośnie wszystkich typów użytkownika w C++)
Interfejs klasy std::any¶
-
any
()¶ domyślny konstruktor, tworzący pusty egzemplarz obiektu klasy
any
-
template<typename
ValueType
>any
(ValueType &&value)¶ szablonowa wersja konstruktora do tworzenia obiektu przechowywującego kopię argumentu typu
ValueType
-
template<typename
ValueType
, class ...Args
>
std::decay_t<ValueType> &emplace
(Args&&... args)¶ Zmienia przechowywany obiekt na nowy typu
ValueType
konstruowany z argumentówargs
-
any &
operator=
(const any &other)¶ jeśli obiekt nie jest pusty, operator przypisania powoduje usunięcie przechowywanej wartości i przyjęcie kopii wartości przechowywanej w
other
-
template<typename
ValueType
>
any &operator=
(ValueType &&value)¶ szablonowa wersja operatora przypisania
-
bool
has_value
() const¶ sygnalizuje stan egzemplarza
any
, zwracająctrue
, jeśli egzemplarz przechowuje jakąkolwiek wartość
-
const std::type_info &
type
() const¶ opisuje typ przechowywanej wartości
-
void
reset
()¶ jeśli obiekt nie jest pusty, przechowywany obiekt jest niszczony
Funkcje zewnętrzne¶
Dwie wersje funkcji szablonowej any_cast
:
-
template<typename
ValueType
>
ValueTypeany_cast
(const any &operand)¶ funkcja
any_cast
udostępnia wartość przechowywaną w obiekcieany
. Argumentem wywołania jest obiektany
, którego wartość ma zostać wyłuskana. Jeśli parametr szablonu funkcjiValueType
nie odpowiada właściwemu typowi przechowywanego elementu rzucany jest wyjątekstd::bad_any_cast
-
template<typename
ValueType
>
ValueType *any_cast
(any *operand)¶ przeciążona wersja
any_cast
, przyjmująca wskaźniki obiektów i zwracająca typowane wskaźniki wartości przechowywanych wany
. Jeśli typValueType
nie odpowiada typowi właściwemu typowi wartości przechowywanej, zwracany jest wskaźnik pusty (nullptr
).
Stosowanie std::any¶
std::any a;
a = std::string("Tekst...");
a = 42;
a = 3.1415;
double pi = std::any_cast<double>(a); // OK
std::string s = std::any_cast<std::string>(a); // rzuca wyjatek std::bad_any_cast
Gadget* g = std::any_cast<Gadget>(&a); // zwraca nullptr
if (g)
g->do_stuff();
else
std::cout << "Niepoprawna konwersja dla obiektu any.\n";
Kontenery heterogeniczne z std::any¶
Klasa std::any
umożliwia przechowywanie w kontenerach standardowych elementów różnych, niezwiązanych ze sobą typów.
void print_any(const std::any& a)
{
// ...
}
std::vector<std::any> store_anything;
store_anything.push_back(A());
store_anything.push_back(B());
store_anything.push_back(C());
store_anything.push_back(Gadget{"ipad"});
//...
for(const auto& obj : store_anything)
print_any(obj);
Obiekty typu std::any w algorytmach standardowych¶
Algorytmy standardowe mogą być wykonywane na heterogenicznych kontenerach zawierających obiekty typu any
.
using namespace std;
// predykat
auto is_int = [](const std::any& a) { return typeid(int) == a.type(); };
vector<std::any> a = { 1, 3.14, "text"s, 42, 44.4f, 665 };
vector<std::any> b;
copy_if(a.begin(), a.end(), back_inserter(b), is_int);