std::any是c++17引入的类型安全单值容器,可存储任意可复制构造类型(如int、std::string、自定义类、std::vector等),但不支持纯右值引用或不可复制类型。
std::any 是什么,能存哪些值
std::any 是 C++17 引入的类型安全容器,用来存储任意可复制(CopyConstructible)类型的单个值。它不是“万能容器”意义上的集合,而是一个“单值泛型盒子”——只能装一个东西,且必须明确知道怎么取出来。
- 可以存
int、std::string、自定义类(满足可复制)、甚至std::vector<double></double> - 不能存纯右值引用、不满足复制构造的类型(如含 deleted 拷贝构造函数的类)
- 不支持直接比较两个
std::any是否相等(需手动type()判断后转型再比) - 存
nullptr是合法的,但存裸指针(如int*)本身没问题,只是要自己管理生命周期
常见误用:把它当 std::vector<:any></:any> 用作动态类型数组——这可行但性能差、易出错,不是设计本意。
怎么安全地存和取值
存值很简单:std::any 构造或赋值即可;取值必须显式使用 std::any_cast,否则运行时报 std::bad_any_cast。
std::any a = 42;
std::any b = std::string("hello");
<p>// ✅ 正确取值:类型匹配
int x = std::any_cast<int>(a); // OK
std::string s = std::any_cast<std::string>(b); // OK</p><p>// ❌ 错误:类型不匹配 → 抛 std::bad_any_cast
// double d = std::any_cast<double>(a);</p><p>// ✅ 安全取值:先检查类型再 cast
if (a.type() == typeid(int)) {
int y = std::any_cast<int>(a);
}
-
std::any_cast<t>(any_obj)</t>要求T和实际存储类型完全一致(包括 const/volatile 限定符) - 支持指针形式
std::any_cast<t>>(&any_obj)</t>,返回T,失败时返回nullptr,适合避免异常 - 不要用
std::any_cast<void>(...)</void>—— 这是未定义行为
和 void* / union / boost::any 对比有什么坑
-
和 void* 比:std::any 自动管理内存和析构,类型信息在运行时保留,但有约 2–3 倍空间开销(内部通常用 small buffer optimization + heap fallback)
立即学习“C++免费学习笔记(深入)”;
-
和 union 比:不需要手动维护活跃字段,但失去编译期类型检查和零成本抽象
和 void* 比:std::any 自动管理内存和析构,类型信息在运行时保留,但有约 2–3 倍空间开销(内部通常用 small buffer optimization + heap fallback)
立即学习“C++免费学习笔记(深入)”;
和 union 比:不需要手动维护活跃字段,但失去编译期类型检查和零成本抽象