讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

AniShort
AniShort

AI短剧协同制作平台

Seko
Seko

AI短剧一键生成成片

C++ std::any 与 std::variant 是什么?(如何替代传统的 void* 和 union)

阿枫姑娘_1080

阿枫姑娘_1080

发布时间:2026-02-12 16:03:14

|

843人浏览过

|

来源于php中文网

原创

std::any用于运行时未知类型的单值存储,依赖动态类型检查;std::variant适用于编译期已知有限类型的高效安全切换,需全覆盖处理。选any当类型完全不确定,选variant当类型集合固定且需高性能分发。

c++ std::any 与 std::variant 是什么?(如何替代传统的 void* 和 union)

std::any 能存任意类型,但取值前必须知道类型

它像一个带类型擦除的“万能盒子”,运行时才检查类型是否匹配。和 void* 不同,std::any 自带类型信息,不会让你在解引用时崩溃——但如果你猜错了类型,std::any_cast 会抛出 std::bad_any_cast 异常。

常见错误现象:std::any_cast<int>(a)</int> 对一个存了 double 的 std::any 调用,直接崩溃(没捕获异常);或者用 std::any_cast<const int></const> 去取一个右值,编译失败。

  • 使用场景:配置项解析、插件系统中传递未知但单次确定的值(比如某个字段可能是 int 或 std::string,但具体哪种由 JSON 字段名决定)
  • 安全取值必须先用 std::any_cast<t>(&a)</t> 检查是否可转,或用 std::any_cast<t>(a)</t> 并包 try/catch
  • 性能影响:每次 std::any_cast 都要动态类型比对,比直接访问慢;内部可能堆分配(小对象优化取决于实现)
  • 别把它当 union 用——它不支持多类型共存,也不提供 switch-case 式的类型分发

std::variant 是编译期限定的“安全 union”

std::variant 在定义时就锁死了能存哪些类型,比如 std::variant<int std::string double></int>。它比原始 union 安全得多:构造、析构、赋值都自动管理活跃成员,不会出现“用 int 覆盖 string 后还调 string 析构函数”的 UB。

常见错误现象:忘记处理所有分支,std::visit 传入的 visitor 缺少对某个类型的重载,导致编译失败;或者用 std::get<t>(v)</t> 强制取值,而当前活跃类型不是 T,抛出 std::bad_variant_access。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

立即学习“C++免费学习笔记(深入)”;

  • 使用场景:状态机返回值(成功/失败/超时)、AST 节点类型(BinaryOp/Literal/Identifier)、协议字段的多种可能取值
  • 必须用 std::visit 处理所有可能类型,推荐用 lambda 模板或 std::overload 辅助类组织逻辑
  • 参数差异:std::get_if<t>(&v)</t> 返回指针,安全但需判空;std::get<t>(v)</t> 更快但不安全,只应在确定类型后使用
  • 内存布局紧凑,无堆分配,访问开销接近原生 union,但多了 1–2 字节的 type index

什么时候选 any,什么时候选 variant?

关键看“类型集合”是编译期可知,还是运行时才确定。

  • 选 std::any:你根本不知道将来会塞什么类型(比如用户脚本传进来的值),且只存不频繁切换
  • 选 std::variant:你知道全部可能类型,且需要高效、无异常地分发处理(比如解析器每步只产出几种固定节点)
  • 别用 std::any 模拟枚举行为——类型太多会导致运行时检查膨胀,也难维护
  • 别用 std::variant 存 “任意类型”,比如 std::variant<:any ...></:any>,这等于放弃类型安全又没换来灵活性

替代 void* 和 union 的真实代价

它们确实消除了裸指针的悬垂风险和 union 的手动生命周期管理,但引入了新约束:类型必须明确、可比较、可拷贝(或移动)。尤其要注意 std::variant 中的类型不能是抽象类、数组或带删除拷贝构造的类型。

  • void* 的自由是以放弃所有类型检查为代价的;std::any 和 std::variant 把检查移到了更早阶段——一个在运行时,一个在编译时
  • 兼容性上,std::any 要求 C++17,std::variant 同样;老项目升级时注意 MSVC/GCC/Clang 版本是否支持完整特性(比如 Clang 5+ 才完全支持 std::variant 的 constexpr 构造)
  • 最容易被忽略的一点:std::variant 的 std::monostate 占位符不是摆设——它让 variant 可默认构造,否则所有类型都得有默认构造函数,这点在设计接口时经常卡住

热门AI工具

更多
函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2355

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3842

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1276

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4479

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7519

2023.08.02

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

1071

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

1457

2024.03.13

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

849

2023.09.27

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

40

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn