17370845950

C++ any类型是什么 C++17存储任意类型数据容器介绍【类型】
std::any适用于运行时类型完全未知且不可穷举的场景;它要求存储类型可复制,访问必须用any_cast显式转换,不支持隐式类型转换,且依赖RTTI,性能低于std::variant。

std::any 是 C++17 引入的类型安全容器,用于在运行时存储任意可复制(CopyConstructible)类型的单个值。它不是泛型模板实例,而是一个具体类型,类似“类型擦除”后的盒子。

什么时候该用 std::any 而不是 std::variant

当你**事先完全不知道可能存什么类型,且类型集合不可穷举**时,std::any 才是合理选择;比如插件系统接收用户传入的任意配置值、反射调用中暂存返回结果。

  • std::variant 要求所有可能类型在编译期明确列出,类型安全更强、开销更小
  • std::any 允许运行时动态决定类型,但每次访问前必须用 any_cast 显式检查并转换,否则抛出 std::bad_any_cast
  • 若类型集合固定且有限(如仅支持数字/字符串/布尔),优先选 std::variant —— 它避免了 RTTI 依赖和堆分配(std::any 内部可能 heap-allocate 大对象)

std::any 的构造与访问必须配对使用 any_cast

直接取值会编译失败,必须通过 any_cast 提取。它有两种形式:引用版(不拷贝)和值版(拷贝),且都要求类型精确匹配(不支持隐式转换)。

  • 正确:std::any a = 42; int x = std::any_cast(a);
  • 错误:std::any_cast(a) → 即使 int 可转 long,也会抛 std::bad_any_cast
  • 安全检查写法:if (auto p = std::any_cast(&a)) { use(*p); },返回 nullptr 表示类型不匹配
  • 移动语义可用:std::any_cast<:string>(a) 可窃取内容,避免拷贝

注意 std::any 不支持无状态类型和某些特殊类型

它要求所存类型满足 CopyConstructible,且内部实现通常依赖 RTTI。以下情况会失败或未定义:

  • std::any(默认构造)调用 any

    _cast
    → 抛 std::bad_any_cast
  • 试图存 void、函数类型、抽象类、数组类型(如 int[5])、或带有删除拷贝构造函数的类 → 编译错误
  • 某些嵌入式或禁用 RTTI 的环境(如 -fno-rtti)下,std::any 可能不可用或行为受限
  • 性能敏感路径慎用:小对象可能栈上存储,但大对象触发堆分配 + 动态类型查询,比直接使用具体类型慢一个数量级

真正难的不是怎么塞进去,而是你怎么确保每次取出来时知道它到底是什么类型——这得靠你自己的逻辑控制,std::any 不帮你记。