c++中的std::variant和std::any的性能对比_c++类型安全容器选择【C++17】

admin 百科 16
c++kquote>std::variant 是编译期确定类型的零开销有限多态容器,栈上存储、无虚调用;std::any 是运行期类型擦除的无限多态容器,依赖堆分配、虚函数和类型检查,性能开销显著。

c++中的std::variant和std::any的性能对比_c++类型安全容器选择【C++17】-第1张图片-佛山资讯网

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*)和拷贝函数指针;赋值还可能引发新分配+旧释放。例如:

标签: 字节 回调函数 c++ switch

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~