What is std::any in C++ and How to Use It
std::any in C++ is a type-safe container that can hold a single value of any type. It allows you to store and retrieve values without knowing their type at compile time, using runtime type information.How It Works
std::any acts like a box that can hold any single item, no matter its type. Imagine you have a magic box where you can put a toy car, a book, or a ball, and later you can take it out and know exactly what it is. This is similar to how std::any stores values.
Under the hood, std::any keeps track of the type of the stored value so you can safely get it back later. If you try to get the value as the wrong type, it will let you know by throwing an exception. This makes it safer than using raw pointers or void pointers, which can cause errors if misused.
Example
This example shows how to store different types in std::any and retrieve them safely.
#include <iostream> #include <any> #include <string> int main() { std::any value; value = 42; // store an int std::cout << "Integer stored: " << std::any_cast<int>(value) << '\n'; value = std::string("Hello std::any"); // store a string std::cout << "String stored: " << std::any_cast<std::string>(value) << '\n'; // Trying to get wrong type throws exception try { std::cout << std::any_cast<int>(value) << '\n'; } catch (const std::bad_any_cast& e) { std::cout << "Exception: " << e.what() << '\n'; } return 0; }
When to Use
Use std::any when you need to store values of different types in the same variable or container, but you don't know the types in advance. It is helpful in situations like configuration settings, event systems, or when interfacing with loosely typed data.
For example, if you have a function that can accept many different types of arguments and you want to store them temporarily without templates or inheritance, std::any is a good choice. However, it is not meant for high-performance code where type safety and speed are critical, because it uses runtime checks.
Key Points
std::anycan hold one value of any type at a time.- It provides type-safe access using
std::any_cast. - Trying to cast to the wrong type throws
std::bad_any_cast. - It is useful for flexible, type-erased storage.
- Introduced in C++17, so requires a compiler that supports C++17 or later.