C++17
std::any
std::any库,它是一种类型安全的容器,可以存储任意类型 的数据。与void*不同,std::any可以检查是否存储了值,并且可以安全地检索和转换存储的值。我们可以使用std::any_cast
函数检索该值,并将其转换为期望的类型,如果类型匹配,则强制转换返回相应的地址指针,如果不匹配,则返回nullptr。若要修改该值,需要转换为对应的引用类型 。如果我们试图从std::any对象中检索不正确的类型,std::bad_any_cast
异常将被抛出。此外,如果std::any对象没有存储任何值,则std::bad_any_cast异常也会被抛出。因此,在使用std::any_cast函数时应谨慎,最好使用std::any::has_value
函数检查std::any对象是否包含值。
c
#include <iostream>
#include <any>
#include <string>
#include <vector>
#include <exception>
int main(int argc, char** argv)
{
std::any a;
try {
std::cout << std::any_cast<int>(a) << std::endl;
} catch (std::exception& e) {
std::cout << "Exception: " << e.what() << std::endl;
}
// check has value
std::cout << "std::any::has_value(): " << a.has_value() << std::endl;
// clear value
a.reset(); // a = std::any{}; 或 a = {};
std::cout << "std::any::has_value(): " << a.has_value() << std::endl;
a = 1;
std::cout << "std::any::has_value(): " << a.has_value() << std::endl;
if (a.type() == typeid(int)) {
std::cout << "std::any::has_value type int" << std::endl;
}
std::cout << std::any_cast<int>(a) << std::endl;
a = 3.1415926; // double
std::cout << std::any_cast<double>(a) << std::endl;
if (a.type() == typeid(double)) {
std::cout << "std::any::has_value type double" << std::endl;
}
a = std::string("Hello"); // std::string
std::cout << std::any_cast<std::string>(a) << std::endl;
// modify value
std::any_cast<std::string&>(a) = "World";
std::cout << std::any_cast<std::string>(a) << std::endl;
std::vector<int> v1 = {1, 2, 3, 4, 5};
a = v1; // vector
std::vector<int> b = std::any_cast<std::vector<int>>(a);
for (auto i : b) {
std::cout << i << " ";
}
std::cout << std::endl;
a = {}; // clear value
std::cout << "---------------------" << std::endl;
std::vector<std::any> v2;
v2.push_back(42);
std::string s = "hello";
v2.push_back(s);
for (const auto& tmp : v2) {
if (tmp.type() == typeid(std::string)) {
std::cout << "type string: " << std::any_cast<const std::string&>(tmp) << std::endl;
} else if (tmp.type() == typeid(int)) {
std::cout << "type int: " << std::any_cast<int>(tmp) << std::endl;
}
}
return 0;
}