std::any不能存储引用或数组,因要求类型满足copyconstructible和moveconstructible;正确做法是存指针或包装类型如std::reference_wrapper、std::array;取值必须用std::any_cast检查类型,否则抛std::bad_any_cast;性能开销来自堆分配,高频使用需谨慎;类型比较需手动分支处理,不支持operator==。

std::any 不能直接存储引用或数组,这是最常踩的坑
试图用 std::any 存 int& 或 char[10] 会编译失败,因为 std::any 要求类型必须满足 CopyConstructible 和 MoveConstructible,而引用和内置数组不满足。常见错误现象是编译器报错:error: use of deleted function 'std::any::any(const std::any&)'(实际更可能是模板实例化失败,提示类似 no matching constructor)。
正确做法只有两种:
- 存指针(
int*、MyClass*),但需自行管理生命周期 - 存包装类型(如
std::reference_wrapper<int></int>替代int&;用std::array<char></char>替代char[10])
例如:
int x = 42;<br>std::any a{std::ref(x)}; // OK<br>std::any b{std::array<char>{"hello"}}; // OK</char>
取值前必须用 std::any_cast 检查类型,否则抛 std::bad_any_cast
std::any_cast 是唯一安全取值方式,但它不做运行时类型自动转换——哪怕 int 和 long 都是整型,也不能互转。一旦类型不匹配,立刻抛 std::bad_any_cast 异常,而不是静默失败或返回默认值。
典型误用场景:
- 忘记检查就直接
std::any_cast<double>(a)</double>,而a实际存的是std::string - 用
std::any_cast<const t></const>取值后,原std::any对象被移动(C++17 起),后续再取会失败
推荐写法是先用 std::any_cast<t></t> 判空:
if (auto p = std::any_cast<:string>(&a)) {<br> std::cout } else {<br> // 类型不匹配,安全跳过<br>}</:string>
std::any 的性能开销主要来自动态内存分配和类型擦除
内部实现通常在堆上分配存储空间(尤其对大于指针大小的类型),每次构造/赋值都可能触发一次 new;小对象优化(small object optimization)是否启用取决于标准库实现,不可依赖。
影响明显的场景:
- 高频存取(如每帧循环中反复构造
std::any)→ 明显 GC 压力或堆碎片 - 存大量小对象(如
std::any{42})→ 即使是int,也可能因对齐要求额外分配 16~32 字节
替代方案考虑:
- 若类型集合固定,优先用
std::variant<t1 t2 ...></t1>—— 零堆分配、编译期类型安全 - 若只是临时传递,且调用方明确知道类型,可改用模板参数或
void*+ 注释说明(更轻量,但失去类型检查)
std::any 不支持 operator==,比较需手动展开类型
没有 operator== 或 operator,想判断两个 <code>std::any 是否“逻辑相等”,必须先确认它们类型相同,再分别 cast 后比较值。容易忽略的点是:类型相同但值语义不同(比如两个 std::vector<int></int> 内容一样,但地址不同)。
一个最小可行的比较辅助函数:
bool any_equal(const std::any& a, const std::any& b) {<br> if (a.type() != b.type()) return false;<br> return std::any_cast<const int>(&a) == std::any_cast<const int>(&b); // 仅示意,需按实际类型分支处理<br>}</const></const>
真正工程中建议避免跨类型比较逻辑,把它推给业务层:让使用者明确知道存的是什么,自己负责比较。
复杂点在于类型分支爆炸——你得为每种可能存入的类型写一套比较逻辑,而且无法静态检查是否覆盖全。这恰恰暴露了 std::any 的本质:它是类型擦除的逃生舱,不是通用容器。用得越深,越要警惕它把类型问题推迟到运行时。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











