any is one of the newest features of C++17 that provides a type-safe container to store single value of any type. In layman’s terms, it is a container which allows one to store any value in it without worrying about the type safety. It acts as an extension to C++ by mimicking behaviour similar to an object type in .NET/Java or void* type in C language . It has been designed based on boost::any and is available in “any” header file.
Syntax:
any var= value/object;
where value is something like “17” or “Hello World”
Initialisation of any:
any can be constructed in three different ways using:
- Copy Initialization
Syntax:
any variable_name = object/value;
- Parameterized constructor / brace initializer.
Syntax:
any variable_name ( object/value);
- Using the assignment operator
Syntax:
any variable_name;
variable_name= object/value;
Converting any_var value into its original type:
One must use any_cast<type>( any_var ) to convert any_var value into its original type. If a stored value has a type other than the one trying to cast to, then a “bad_any_cast” exception will be thrown by the compiler.
Note: The type during the cast must exactly be same as the original type. There is no automatic promotion or demotion during the cast. Hence special care must be taken while casting the value to its original type.
A Simple Example ( Illustrates the construction / reading values of any)
#include <any>
#include <iostream>
#include <string>
using namespace std;
int main()
{
try {
any value = 42;
cout << "\n Value: "
<< any_cast< int >(value);
value = "Hello World" ;
cout << "\n Value: "
<< any_cast< const char *>(value);
any val(19.0);
cout << " \n Value: "
<< any_cast< double >(val);
any val_brace{ string( "Brace Initialisation" ) };
cout << " \n Value: "
<< any_cast<string>(val_brace);
}
catch (bad_any_cast& e) {
cout << "\n"
<< e.what();
}
return 0;
}
|
Output:
Value: 42
Value: Hello World
Value: 19
Value: Brace Initialisation
Member functions:
- emplace : Changes the contained object, constructing the new object directly
- reset : Destroys the contained object ( Calls the destructor of the object)
- has_value : Checks if the “any_variable” holds a value within it
- type : Returns the type id of the contained value
Lets see the methods one by one in detail:
Uses of any
Typical uses include
- In Libraries, When a library type has to hold or pass anything without knowing the set of available types.
- Message Passing
- Implementing Parser Libraries for ex. JSON parser
- User Interface: controls might hold anything
- Entity component system.
One of the main benefits of any is its viable substitution with void*. void* has limited capability( Only stores pointer types) and is considered as an unsafe pattern.
Error Handling:
There are two options regarding error handling for any class:
- Using Exceptions: bad_any_cast is the exception thrown by the value-returning forms of any_cast on type-mismatch.
Example:
#include <any>
#include <iostream>
#include <string>
int main()
{
try {
any var = 12.0f;
cout << " \n Value: "
<< any_cast< double >(var);
}
catch (bad_any_cast& e) {
cout << "\n"
<< e.what();
}
return 0;
}
|
Output
Value:
bad any_cast
-
Returning a Pointer: Returning a pointer is useful when the exception mechanism has been disabled in the compiler. This particular overload of any_cast returns the pointer to the contained object if the cast was successful and returns nullptr.
Example:
#include <any>
#include <iostream>
#include <string>
using namespace std;
int main()
{
any var = 12.0f;
auto * tval = any_cast< float >(&var);
if (!tval) {
cout << " \n Bad_any_cast " ;
}
else {
cout << " \n Value: "
<< *tval;
}
return 0;
}
|
Output:
Value: 12
Memory Considerations
Although any gives a lot of flexibility with the language, the main issue with any is extra dynamic memory allocations. As the container is not aware of object contained dynamic allocation becomes a must for any.
But according to the standard, Implementations should avoid the use of dynamically allocated memory for a small contained value. Example: where the object constructed is holding only an int. Such small-object optimisation shall only be applied to types T for which is_nothrow_move_constructible_v true.
What this typically means is that the compiler must use small buffer optimization ( SBO) in which a certain amount of memory has to be reserved for the type to be contained.

From the table above, one can see that reserved memory for SBO in some cases could go upto 64 bytes! ( MSVC-64 bit). This means that each object of any would require 64 bytes of memory reserved even if the object is small which is a considerable memory overhead.
Although any is a very powerful feature in C++. It comes with a considerable amount of overhead in terms of memory.
Similar Reads
Nested Classes in C++
A nested class is a class which is declared in another enclosing class. A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed. For example, p
1 min read
std::string class in C++
C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. The string class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character. String vs Character ArrayString Ch
8 min read
Anonymous classes in C++
Anonymous class is a class which has no name given to it. C++ supports this feature. These classes cannot have a constructor but can have a destructor. These classes can neither be passed as arguments to functions nor can be used as return values from functions. Examples to illustrate Anonymous Clas
3 min read
STD::array in C++
The array is a collection of homogeneous objects and this array container is defined for constant size arrays or (static size). This container wraps around fixed-size arrays and the information of its size are not lost when declared to a pointer. In order to utilize arrays, we need to include the ar
5 min read
std::hash class in C++ STL
In C++, the hash class is default constructible function class (functor) that provides the default hash function used by STL. It is used to get the hash value of the argument that is being passed to it. If the argument doesn't change, the value doesn't change either. Letâs take a quick look at an ex
4 min read
bitset any() in C++ STL
The bitset::any() is an inbuilt function in C++ STL which returns True if at least one bit is set in a number. It returns False if all the bits are not set or if the number is zero. Syntax: bool any() Parameter: The function does not accepts any parameter. Return Value: The function returns a boolea
2 min read
is_class template in C++
The std::is_class template of C++ STL is used to check whether the given type is class or not. It returns a boolean value showing the same. Syntax: template <class T> struct is_class; Parameter: This template accepts single parameter T (Trait class) to check whether T is a class or not. Return
2 min read
Trivial classes in C++
When a class or struct in C++ has compiler-provided or explicitly defaulted special member functions, then it is a trivial type. It occupies a contiguous memory area. It can have members with different access specifiers. Trivial types have a trivial default constructor, trivial copy constructor, tri
1 min read
any_of() Function in C++ STL
any_of() is the C++ function defined in <algorithm> library in STL. This function determines whether even one element in a given range satisfies a specified criterion. If at least one element meets the property, then it returns true; otherwise, it returns false. Also if the range is empty then
2 min read
C++ Classes and Objects
In C++, classes and objects are the basic building block that leads to Object-Oriented programming in C++. We will learn about C++ classes, objects, look at how they work and how to implement them in our C++ program. C++ ClassesA class is a user-defined data type, which holds its own data members an
10 min read