std::any
是 C++17 引入的一个标准库类型,用于存储任意类型的值。它类似于其他语言中的“动态类型”或“泛型容器”,允许你在运行时存储和操作不同类型的值,而不需要提前知道具体的类型。
std::any
的主要特点:
-
类型安全:
std::any
在存储和提取值时保持类型安全。如果你尝试提取的类型与存储的类型不匹配,它会抛出std::bad_any_cast
异常。 -
动态类型:你可以在
std::any
中存储任何类型的值,包括基本类型(如int
、double
)、自定义类、指针等。 -
值语义:
std::any
存储的是值的副本,而不是引用或指针。
std::any
的主要操作:
-
构造和赋值:你可以通过构造函数或赋值操作将任何类型的值存储到
std::any
中。 -
类型检查:使用
type()
方法可以获取当前存储值的类型信息。 -
值提取:使用
std::any_cast
可以将std::any
中的值提取出来。如果类型不匹配,会抛出异常。
#include <iostream>
#include <any>
#include <string>
#include <vector>
#include <typeinfo>
// 自定义类
class MyClass {
public:
MyClass(const std::string& name, int value) : name(name), value(value) {}
void print() const {
std::cout << "MyClass: name = " << name << ", value = " << value << std::endl;
}
private:
std::string name;
int value;
};
// 通用函数,处理 std::any 类型的值
void processAny(const std::any& any_value) {
if (any_value.type() == typeid(int)) {
std::cout << "Processing int: " << std::any_cast<int>(any_value) << std::endl;
} else if (any_value.type() == typeid(std::string)) {
std::cout << "Processing string: " << std::any_cast<std::string>(any_value) << std::endl;
} else if (any_value.type() == typeid(double)) {
std::cout << "Processing double: " << std::any_cast<double>(any_value) << std::endl;
} else if (any_value.type() == typeid(MyClass)) {
std::cout << "Processing MyClass: ";
std::any_cast<MyClass>(any_value).print();
} else {
std::cerr << "Unknown type: " << any_value.type().name() << std::endl;
}
}
int main() {
// 创建一个 std::vector<std::any>,存储不同类型的值
std::vector<std::any> any_values;
// 存储不同类型的值
any_values.push_back(42); // int
any_values.push_back(3.14); // double
any_values.push_back(std::string("Hello")); // std::string
any_values.push_back(MyClass("Foo", 100)); // 自定义类 MyClass
// 遍历 vector,处理每个 std::any 值
for (const auto& value : any_values) {
try {
processAny(value);
} catch (const std::bad_any_cast& e) {
std::cerr << "Error processing value: " << e.what() << std::endl;
}
}
// 尝试存储和提取一个指针类型
int* ptr = new int(99);
any_values.push_back(ptr); // 存储指针
// 处理指针类型
try {
if (any_values.back().type() == typeid(int*)) {
int* extracted_ptr = std::any_cast<int*>(any_values.back());
std::cout << "Processing pointer: " << *extracted_ptr << std::endl;
delete extracted_ptr; // 清理动态分配的内存
}
} catch (const std::bad_any_cast& e) {
std::cerr << "Error processing pointer: " << e.what() << std::endl;
}
return 0;
}