
std::variant 和 std::any 都是 C++17 引入的类型安全容器,但设计目标和性能特征差异显著——variant 是编译期确定类型的“有限多态”,any 是运行期擦除类型的“无限多态”。性能上,variant 几乎无额外开销,any 则有动态内存、虚函数调用和类型信息查找等成本。
内存布局与访问开销
std::variant 在栈上直接存储其可选类型的**最大尺寸 + 1 字节(用于存放当前索引)**,访问时通过编译期生成的 switch 或跳转表完成,零运行时类型检查开销。例如:
std::variant<int, double, std::string> v = 42; // 访问 int:直接取地址偏移,无虚调用、无 new/delete
登录后复制
std::any 则内部持有一个指向堆内存的指针(除非小对象优化 SOO 生效),且每次访问需:
- 调用 typeid 对比判断类型是否匹配
- 若匹配,再解引用并 static_cast
- 构造/析构过程涉及虚函数(如 std::any::holder 的 ~holder())
构造与赋值代价
variant 构造是 trivial 的(若所含类型都 trivial),即使非 trivial 类型,也只调用对应分支的构造函数,无额外抽象层。
立即学习“C++免费学习笔记(深入)”;
any 的构造必然触发一次堆分配(除非 SOO 触发),且需保存类型信息(std::type_info*)和拷贝函数指针;赋值还可能引发新分配+旧释放。例如:
还木有评论哦,快来抢沙发吧~