新闻中心
C++怎么使用std::any和std::variant_C++17类型安全容器详解
std::any可存储任意类型,适用于类型未知但需安全访问的场景;std::variant是类型安全的联合体,适用于预定义类型的集合,二者均避免了void*的类型不安全问题。

在C++17中,std::any 和 std::variant 是两个新增的类型安全容器,它们解决了传统 void* 或联合体(union)带来的类型不安全问题。虽然两者都能存储不同类型的数据,但适用场景和设计目标不同。下面详细介绍它们的使用方法与区别。
std::any:任意类型的容器
std::any 可以保存任意单一类型的值,类似于“万能盒子”。它适用于你无法提前知道要存储什么类型,但又需要类型安全的场景。
基本用法:
GoEnhance
全能AI视频制作平台:通过GoEnhance AI让视频创作变得比以往任何时候都更简单。
347
查看详情
- 包含头文件:
#include <any></any> - 创建 any 对象并赋值:
std::any a = 42; // 存整数<br>a = std::string("hello"); // 改为字符串
访问值的方法:
- 使用
std::any_cast提取值,注意类型必须匹配,否则抛出std::bad_any_cast异常:
try {<br> int value = std::any_cast<int>(a);<br>} catch (const std::bad_any_cast&) {<br> // 类型错误处理<br>}
- 也可以用指针形式避免异常:
if (auto p = std::any_cast<double>(&a)) {<br> std::cout << *p;<br>} else {<br> std::cout << "not doubl
e";<br>}
注意事项:
- any 不支持直接比较操作(==, !=)
- 性能开销较大,因为涉及动态内存分配和类型信息存储
- 适合配置、参数传递等灵活性要求高的场景
std::variant:类型受限的多选一容器
std::variant 是一个“类型安全的联合体”,只能保存其模板参数中列出的某一种类型。相比 any 更高效且可控。
基本用法:
- 包含头文件:
#include <variant></variant> - 定义可存储的类型列表:
std::variant<int, std::string, double> v;<br>v = 42; // ok<br>v = "hello"s; // ok<br>// v = true; // 编译错误,bool 不在允许列表中
访问 variant 中的值:
- 使用
std::get<t>(v)</t>或std::get<index>(v)</index>,类型或索引错误会抛出std::bad_variant_access - 更推荐使用
std::visit进行类型安全的访问:
std::visit([](const auto& val) {<br> std::cout << val;<br>}, v);
visit 会根据当前存储的类型自动调用对应的 lambda 分支,是处理 variant 的最佳实践。
初始化与状态检查:
- 默认构造时,variant 会初始化为其第一个类型的默认值(前提是该类型可默认构造)
- 可用
std::holds_alternative<t>(v)</t>检查当前是否存的是某种类型:
if (std::holds_alternative<std::string>(v)) {<br> std::cout << "it's a string";<br>}
any 与 variant 如何选择?
关键在于使用场景:
- 需要存储完全未知的类型,比如插件系统、反射机制、通用容器 —— 用 std::any
- 已知可能的类型集合,比如表达式求值中的 int/double/string,JSON 基本类型 —— 用 std::variant
variant 性能更好,类型更明确,编译期可检查;any 更灵活但运行时开销大。
常见陷阱与建议
- 不要对 any 频繁使用 any_cast,容易出错,建议配合 type info 判断
- variant 中如果某个类型不可默认构造,需显式初始化
- 使用 visit 时,lambda 要能处理所有可能类型,否则编译失败
- 避免嵌套过深的 variant,会影响可读性和性能
基本上就这些。std::any 和 std::variant 让 C++ 在保持类型安全的前提下拥有了更强的泛型能力,合理使用可以替代不少不安全的 void* 或 union 用法。
以上就是C++怎么使用std::any和std::variant_C++17类型安全容器详解的详细内容,更多请关注其它相关文章!
# 第一个
# 静安抖音营销推广电话
# 网站seo关键词分类
# 商业内容关键词排名
# 合肥网站建设的微博
# 济南seo公司推荐
# seo49
# 福州排名seo公司
# 网站SEO优化案例分析
# 天门网站如何推广
# 手机病毒网站建设海报图
# c++
# 迭代
# 头文件
# 是一个
# 的是
# 命令行
# 抛出
# 解决方法
# 适用于
# 不安全
# 区别
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
抖音DOU+怎么投最有效 抖音付费推广的ROI提升技巧
J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案
魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】
如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略
AO3中文官网链接_AO3网页版稳定镜像站
谷歌google账号注册详细步骤 谷歌账号注册官方教程
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
《燕云十六声》两周内达九百万玩家!位居畅销榜第五
电脑屏幕颜色不舒服怎么办_Windows夜间模式与色彩校准教程【护眼技巧】
age动漫网站入口 age动漫官网直接访问入口
海量存储:机器视觉智能化的核心基石
Highcharts 雷达图径向轴标签定制指南:利用多Y轴实现数值标注
qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程
苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】
微信网页版官方入口教程 微信网页版网页版快速登录步骤
如何将HTML表格多行数据保存到Google Sheet
Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】
AO3网页版最新入口合集 Archive of Our Own在线访问指南
印象笔记怎样用批量导出备知识库_印象笔记用批量导出备知识库【备份方法】
Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】
MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具
Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】
使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战
PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符
12306选座怎么选到商务座_12306商务座选择与配置说明
Python字典中优雅地迭代剩余元素的方法
12306怎么选座位选到安静区_12306选座安静区域选择策略
使用 Pandas 高效处理 .dat 文件:字符清理与数据计算
响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配
黑鲨3Pro怎样在相册开漫画风滤镜_iPhone黑鲨3Pro相册开漫画风滤镜【趣味滤镜】
快手赚钱渠道_快手收益来源
PHP中获取MongoDB服务器运行时间(Uptime)的专业指南
解决Bootstrap卡片顶部边距导致背景图下移的问题
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
必由学在线入口 必由学网页版快速登录入口
在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案
QQ邮箱电脑版登录入口_QQ邮箱官方网站登录平台
如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension
React/Next.js中实现列表项的动态移动与状态管理:兼论唯一键的重要性
蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗
想当下一个《2077》?《心之眼》Steam评价升至"多半好评"
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
网站内容防复制粘贴的实现策略与局限性
J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析
如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构
Golang如何测试channel通信行为_Golang channel通信测试与分析方法
AO3官方可用镜像 Archive of Our Own网页版最新入口
CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡


2025-12-03
浏览次数:次
返回列表
e";<br>}