0

0

c++如何使用variant类型_c++17安全联合体用法【核心】

穿越時空

穿越時空

发布时间:2026-02-24 16:50:46

|

828人浏览过

|

来源于php中文网

原创

std::variant 是类型安全的可变容器,强制记录当前持有的类型,不可当作普通 union 直接内存读写;必须用 std::holds_alternative 判断、std::get 或 std::get_if 安全访问、emplace 或赋值切换类型。

c++如何使用variant类型_c++17安全联合体用法【核心】

std::variant 是什么,为什么不能当普通 union 用

std::variant 不是 union 的语法糖,而是一个类型安全的“可变容器”——它在任意时刻只持有其中一种类型,并且**强制记录当前实际持有的类型**。直接按 memory layout 当 union 读写(比如 reinterpret_cast 或 memcpy)会触发未定义行为,因为 variant 内部有 type index 和可能的就地构造/析构逻辑。

常见错误现象:std::get<int>(v)</int>std::bad_variant_access;或读取非当前活跃类型的值看似“成功”,实则踩内存、结果不可预测。

  • 必须用 std::holds_alternative<t>(v)</t> 先判断当前是否持有 T 类型
  • 获取值必须用 std::get<t>(v)</t>(静态类型检查)或 std::get_if<t>(&v)</t>(返回指针,安全但需判空)
  • 赋值或修改请用 v = T{...}v.emplace<t>(...)</t>,不要手动 placement new

如何安全地初始化和切换 variant 中的类型

variant 构造时默认调用第一个备选类型的默认构造函数(除非显式禁止)。若第一个类型无可默认构造,编译失败。切换类型不是“覆盖内存”,而是先析构旧值、再就地构造新值。

使用场景:状态机中的不同状态数据、解析 JSON 时的 number/string/bool/null 混合字段、事件系统中携带不同类型 payload。

Paraflow
Paraflow

AI产品设计智能体

下载

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

  • 初始化: std::variant<int std::string double> v = 42;</int> → 持有 int
  • 切换: v = std::string{"hello"}; → 自动析构 int,构造 string
  • 强制构造特定类型: v.emplace<double>(3.14);</double> → 跳过赋值运算符,直接调用 double 构造函数
  • 避免隐式转换干扰:把 int 放在 long long 前面,否则 v = 42 可能被推导为 long long

访问 variant 的三种方式及各自风险

不推荐裸用 std::get,尤其在运行时类型不确定时。std::visit 是最安全、最通用的访问方式,但写法略冗长;std::get_if 适合单类型试探;std::get 仅适用于编译期已知类型的分支(如 switch 表达式配合 index())。

  • std::get<int>(v)</int>:抛异常,不建议在无把握时用
  • auto* p = std::get_if<:string>(&v); if (p) use(*p);</:string>:安全,但要手动判空
  • std::visit([](const auto& x) { /* ... */ }, v);:类型安全,支持泛型处理,但 lambda 必须对所有备选类型都可调用(可用 if constexpr 分支)
  • 注意:lambda 参数类型是 const 引用,修改需用 std::get 配合非 const 引用或指针,或改用 std::visit 的非常量重载

性能与 ABI 兼容性要注意什么

std::variant 的大小通常是所有备选类型 size 最大值 + sizeof(index),对齐按最大对齐要求。它不保证 trivially copyable,因此不能用于 memcpy、跨 DLL 边界传递或作为 C 接口参数。

  • 小对象(如 intbool)无额外开销;含 string/vector 等类型时,variant 占用空间大,但仍是栈分配,避免堆分配延迟
  • 移动语义完整支持:move 构造/赋值会转移内部值(如 string 的 move),比拷贝快
  • Windows MSVC 和 GCC/Clang 在 ABI 上基本一致,但若 variant 定义在头文件中被多个 TU 包含,确保所有地方看到完全相同的模板实参顺序和类型定义(尤其是别名展开后)
  • 调试时注意:GDB/LLDB 对 variant 的显示支持有限,print v.index()print v 可能只显示部分信息,必要时用 std::visit 打印

真正难的不是怎么写 variant,而是想清楚哪些类型该放进同一个 variant —— 类型太多会让 std::visit 分支爆炸,类型之间语义无关会破坏封装。宁可拆成两个 variant,也不要塞进一个“万能容器”。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

448

2023.08.07

json是什么
json是什么

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

544

2023.08.23

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

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

323

2023.10.13

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

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

81

2025.09.10

python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

192

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

13

2026.02.03

string转int
string转int

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

850

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

246

2023.09.22

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

1

2026.02.24

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10.1万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 19.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号