This content originally appeared on DEV Community and was authored by Marcos Oliveira
Say goodbye to void*
once and for all.
std::any
is a feature of the C++ standard library that was introduced in C++17.
This component belongs to the set of type-safe container classes, providing a safe means to store and manipulate values of any type.
It is especially useful when you need to deal with situations where the type of the variable can vary!
Then you say:
– Oh man! Good. For these cases I use
void *
.
Yes, you’re really right, but have you seen how the new generation is in relation to memory safety???
Not to mention that void*
is really dangerous!
If you do this, it works:
void * some_data; // Bad idea
std::string str = "Hi";
int x = 3;
decltype(x) y = 6;
some_data = &str;
std::cout << *(std::string*)some_data << '\n';
some_data = &x;
std::cout << *(int*)some_data << '\n';
some_data = &y;
std::cout << "Type of y: " << typeid(y).name() << '\n'; // include typeinfo
But, the chance of this giving mer%$a
is great! At the end of using these variables, some_data
will continue to exist, that is, an indefinite lifetime!
And it is to replace void*
that std::any
was created in Modern C++ which, of course, is totally Safe!
In other words, it is a wrapper that encapsulates your variable to a shared_ptr
(smart pointers) of life! Yes, and there is even a std::make_any
!!!
How to use std::any
First you need to include its header:
Logically, it only works from C++17 as was said at the beginning!
#include <any>
And now the same code that was presented above, but using std::any
:
#include <iostream>
#include <any>
int main(){
std::any some_data;
std::string str = "Hi";
int x = 3;
auto y = std::make_any<decltype(x)>(6);
some_data = str;
std::cout << std::any_cast<std::string>(some_data) << '\n';
some_data = x;
std::cout << std::any_cast<int>(some_data) << '\n';
some_data = y;
std::cout << "Type of y: " << some_data.type().name() << '\n';
}
In the code above we saw that:
-
std::any some_data;
– Declares the variable; -
std::any_cast<T>(some_data)
– Converts to the desired type; -
std::make_any<T>
– Another way to create objects; -
some_data.type().name()
– Gets the data type without needingtypeinfo
.
And you can use it for absolutely everything: std::vector
, Lambda and all existing data types!
And the guy asks something else:
– OK! What if I want to end the lifetime of
std::any
manually?
Just use the reset
union structure or even the initialization operator:
some_data.reset();
// Or
some_data = {};
— And to check if
std::any
is empty?
Use has_value()
:
std::cout << (some_data.has_value() ? "Full!" : "Empty.") << '\n';
The unionless type()
with name()
can be used to compare types:
std::cout << (some_data.type() == typeid(void)) << '\n'; // 0 to false
std::cout << (some_data.type() == typeid(int)) << '\n'; // 1 to true
To use Boolean names use:
std::cout << std::boolalpha << (some_data.type() == typeid(int)) << '\n';
.
To throw exceptions you must use std::bad_any_cast
:
try {
std::any any_str("Hiii");
auto my_any{ std::make_any<std::string>(any_str.type().name()) };
std::cout << std::any_cast<std::string>(my_any) << '\n';
}catch (const std::bad_any_cast& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
To check whether everything really complies, never forget to use the flags for your compiler: -Wall -Wextra -pedantic -g -fsanitize=address
.
In addition to being completely SAFE, std::any
is very practical and a great help!
There was a company project that I was developing, which passed a function argument and could be any type, but the function’s return was std::string
concatenated to the name of the object received.
And someone had created a great switch case
to convert to std::string
(bizarre!), I substituted it to receive the parameter for std::any
and converted it with std::any_cast< std::string>
and I solved it in a way: Modern, Safe and Like a Boss! Exactly what std::any
is!!!
For more information visit: https://en.cppreference.com/w/cpp/utility/any
This content originally appeared on DEV Community and was authored by Marcos Oliveira