std::any Class in C++

19 Nov, 2018
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”
any can be constructed in three different ways using:
Copy InitializationSyntax:any variable_name = object/value;
Parameterized constructor / brace initializer.Syntax:any variable_name ( object/value);
Using the assignment operatorSyntax: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 {          // Integer 42:  Using the copy initialisation        any value = 42;        cout << "\n Value: "             << any_cast<int>(value);          // Using the assignment operator        // to store a string        value = "Hello World";        cout << "\n Value: "             << any_cast<const char*>(value);          // Using the parametrized constructor        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 directlyreset : Destroys the contained object ( Calls the destructor of the object)has_value : Checks if the “any_variable” holds a value within ittype : Returns the type id of the contained valueLets see the methods one by one in detail:emplace: emplace member function is similar to the assignment operator and is used to change the contained object with a new object.Program:// C++ program to demonstrate// emplace() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any value = 4.2;        cout << " \n Value:  "             << any_cast<double>(value);          value.emplace<int>(44);        cout << " \n Value:  "             << any_cast<int>(value);    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Value:  4.2 
Value:  44
reset: It destroys the contained object by calling the destructor of the contained object.Program:// C++ program to demonstrate// reset() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 4.2;        cout << " \n Value:  "             << any_cast<double>(var);          var.reset();        if (!var.has_value())            cout << " \n No value found in var variable";    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Value:  4.2 
No value found in var variable
has_value: This member function is used to check whether the object contains a value or notProgram:// C++ program to demonstrate// has_value() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 9.5;        cout << " \n Value:  "             << any_cast<double>(var);          if (var.has_value())            cout << " \n Value found of type "                 << var.type().name();    }      catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output: Value:  9.5 
 Value found of type d
type: This member function returns a type_info structure that can be used to get the properties of the stored object.Program:// C++ program to demonstrate// type() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 12.0f;        cout << " \n Type:  "             << var.type().name();          var = "Hello World";        cout << " \n Type:  "             << var.type().name();    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Type:  f 
Type:  PKc
Uses of anyTypical uses includeIn Libraries, When a library type has to hold or pass anything without knowing the set of available types.Message PassingImplementing Parser Libraries for ex. JSON parserUser Interface: controls might hold anythingEntity 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:// C++ program to demonstrate// using exceptions of any class  #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;}OutputValue:  
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:// C++ program to demonstrate// returning pointer of any class  #include <any>#include <iostream>#include <string>using namespace std;  int main(){    any var = 12.0f;      // Special Overload of any_cast    auto* tval = any_cast<float>(&var);    if (!tval) {          // Type-mismatch        cout << " \n Bad_any_cast ";    }    else {          // Value of the object        cout << " \n Value:  "             << *tval;    }      return 0;}Output:Value:  12
Memory ConsiderationsAlthough 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.My Personal Notes
arrow_drop_upSave
Copy InitializationSyntax:any variable_name = object/value;

Syntax:
any variable_name = object/value;

Parameterized constructor / brace initializer.Syntax:any variable_name ( object/value);

Syntax:
any variable_name ( object/value);

Using the assignment operatorSyntax:any variable_name;
variable_name= object/value;

Syntax:
any variable_name;
variable_name= object/value;

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 {          // Integer 42:  Using the copy initialisation        any value = 42;        cout << "\n Value: "             << any_cast<int>(value);          // Using the assignment operator        // to store a string        value = "Hello World";        cout << "\n Value: "             << any_cast<const char*>(value);          // Using the parametrized constructor        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

emplace : Changes the contained object, constructing the new object directlyreset : Destroys the contained object ( Calls the destructor of the object)has_value : Checks if the “any_variable” holds a value within ittype : Returns the type id of the contained value
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:
emplace: emplace member function is similar to the assignment operator and is used to change the contained object with a new object.Program:// C++ program to demonstrate// emplace() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any value = 4.2;        cout << " \n Value:  "             << any_cast<double>(value);          value.emplace<int>(44);        cout << " \n Value:  "             << any_cast<int>(value);    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Value:  4.2 
Value:  44

Program:
// C++ program to demonstrate// emplace() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any value = 4.2;        cout << " \n Value:  "             << any_cast<double>(value);          value.emplace<int>(44);        cout << " \n Value:  "             << any_cast<int>(value);    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}
Output:
Value:  4.2 
Value:  44

reset: It destroys the contained object by calling the destructor of the contained object.Program:// C++ program to demonstrate// reset() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 4.2;        cout << " \n Value:  "             << any_cast<double>(var);          var.reset();        if (!var.has_value())            cout << " \n No value found in var variable";    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Value:  4.2 
No value found in var variable

Program:
// C++ program to demonstrate// reset() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 4.2;        cout << " \n Value:  "             << any_cast<double>(var);          var.reset();        if (!var.has_value())            cout << " \n No value found in var variable";    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}
Output:
Value:  4.2 
No value found in var variable

has_value: This member function is used to check whether the object contains a value or notProgram:// C++ program to demonstrate// has_value() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 9.5;        cout << " \n Value:  "             << any_cast<double>(var);          if (var.has_value())            cout << " \n Value found of type "                 << var.type().name();    }      catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output: Value:  9.5 
 Value found of type d

Program:
// C++ program to demonstrate// has_value() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 9.5;        cout << " \n Value:  "             << any_cast<double>(var);          if (var.has_value())            cout << " \n Value found of type "                 << var.type().name();    }      catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}
Output:
 Value:  9.5 
 Value found of type d

type: This member function returns a type_info structure that can be used to get the properties of the stored object.Program:// C++ program to demonstrate// type() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 12.0f;        cout << " \n Type:  "             << var.type().name();          var = "Hello World";        cout << " \n Type:  "             << var.type().name();    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}Output:Type:  f 
Type:  PKc

Program:
// C++ program to demonstrate// type() method of any class  #include <any>#include <iostream>#include <string>  int main(){    try {        any var = 12.0f;        cout << " \n Type:  "             << var.type().name();          var = "Hello World";        cout << " \n Type:  "             << var.type().name();    }    catch (bad_any_cast& e) {        cout << "\n"             << e.what();    }    return 0;}
Output:
Type:  f 
Type:  PKc

Typical uses include
In Libraries, When a library type has to hold or pass anything without knowing the set of available types.Message PassingImplementing Parser Libraries for ex. JSON parserUser Interface: controls might hold anythingEntity component system.
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.
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:// C++ program to demonstrate// using exceptions of any class  #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;}OutputValue:  
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:// C++ program to demonstrate// returning pointer of any class  #include <any>#include <iostream>#include <string>using namespace std;  int main(){    any var = 12.0f;      // Special Overload of any_cast    auto* tval = any_cast<float>(&var);    if (!tval) {          // Type-mismatch        cout << " \n Bad_any_cast ";    }    else {          // Value of the object        cout << " \n Value:  "             << *tval;    }      return 0;}Output:Value:  12

Using Exceptions: bad_any_cast is the exception thrown by the value-returning forms of any_cast on type-mismatch.Example:// C++ program to demonstrate// using exceptions of any class  #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;}OutputValue:  
bad any_cast

Example:
// C++ program to demonstrate// using exceptions of any class  #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:// C++ program to demonstrate// returning pointer of any class  #include <any>#include <iostream>#include <string>using namespace std;  int main(){    any var = 12.0f;      // Special Overload of any_cast    auto* tval = any_cast<float>(&var);    if (!tval) {          // Type-mismatch        cout << " \n Bad_any_cast ";    }    else {          // Value of the object        cout << " \n Value:  "             << *tval;    }      return 0;}Output:Value:  12

Example:
// C++ program to demonstrate// returning pointer of any class  #include <any>#include <iostream>#include <string>using namespace std;  int main(){    any var = 12.0f;      // Special Overload of any_cast    auto* tval = any_cast<float>(&var);    if (!tval) {          // Type-mismatch        cout << " \n Bad_any_cast ";    }    else {          // Value of the object        cout << " \n Value:  "             << *tval;    }      return 0;}
Output:
Value:  12

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.
cpp-advanced
cpp-data-types
C++
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Sorting a vector in C++
Polymorphism in C++
std::string class in C++
Friend class and function in C++
Pair in C++ Standard Template Library (STL)
Queue in C++ Standard Template Library (STL)
Unordered Sets in C++ Standard Template Library
std::find in C++
List in C++ Standard Template Library (STL)
Inline Functions in C++