Modern C++ std::visit从实践到原理
前言
std::visit 是 C++17 中引入的一个模板函数,它用于对给定的 variant、union 类型或任何其他兼容的类型执行一个访问者操作。这个函数为多种可能类型的值提供了一种统一的访问机制。使用 std::visit,你可以编写更通用和灵活的代码,而无需关心具体是哪种类型的值。
实践
市面上大部分例子都是只访问一个variant, 我们写个不同的,实际visit支持一下放入多个variant, 参考语法:

#include <iostream>
#include <variant>
#include <string>
using namespace std;// Define alternative types
using Variant1 = std::variant<int, double>;
using Variant2 = std::variant<int,char>;struct MyVisitor {//对每一种组合都必须定义一个处理函数。少一个编译都会失败。void operator()(int value1, int value2) const {std::cout << value1<<value2<<endl;}void operator()(int value1, char value2) const {std::cout << value1<<value2<<endl;}void operator()(double value1, int value2) const {std::cout << value1<<value2<<endl;}void operator()(double value1, char value2) const {std::cout <<value1<<value2<<endl;}
};int main() {Variant1 var1;Variant2 var2;var1 = 42;var2 = 100;std::visit(MyVisitor{}, var1, var2); var1 = 3.14;var2 = 'a';std::visit(MyVisitor{}, var1, var2);return 0;
}
啰嗦一句,因为我们四个函数体相似,正是用模板的好时机,把它们改成一句话:
void operator()(auto&& value1, auto&& value2) const {std::cout << value1<<value2<<endl; }
如果不放心,丢到cppinsights里看看展开:
四个函数不论手写还是自动生成缺一不可,它们其实是两个variant的alternative types的组合,即int/double 与 int/char的所有组合。缺一不可和gcc的实现有关,下面会说到。
visit的原理
这次我们不看晦涩的代码,而是通过GDB快速理解visit的原理。
调试到21行 std::visit(MyVisitor{}, var1, var2);
s进入,慢慢到下面这个位置:

打印__vtable: 它生成了一个2*2的二维数组,里面放了函数指针,对应所有组合。
不要被名字所误解,vtable不是virtual table的意思。

此时var1 var2里面装的都是int,都是各自类型列表中的第一个类型 (var1.index(), var2.index()), __func_ptr应该取得了__vtable[0][0]的值即0x40160f

确实如此。
咱们这是从现象推原理,如果还想了解vtable怎么生成的,可能这篇文章对你有帮助:
Variant Visitation – Michael Park
Variant Visitation V2 – Michael Park
相关文章:
Modern C++ std::visit从实践到原理
前言 std::visit 是 C17 中引入的一个模板函数,它用于对给定的 variant、union 类型或任何其他兼容的类型执行一个访问者操作。这个函数为多种可能类型的值提供了一种统一的访问机制。使用 std::visit,你可以编写更通用和灵活的代码,而无需关…...
谷歌gemma2b windows本地cpu gpu部署,pytorch框架,模型文件百度网盘下载
简介 谷歌DeepMind发布了Gemma,这是一系列灵感来自用于Gemini相同研究和技术的开放模型。开放模型适用于各种用例,这是谷歌非常明智的举措。有2B(在2T tokens上训练)和7B(在6T tokens上训练)模型,包括基础和指令调整版本。在8192个token的上下文长度上进行训练。允许商业使…...
数据结构-查找与排序
数据结构再往后就是比较零散的各种操作,查找与排序是其中最常出现的,今天来总结一下常用的查找与排序所用的方法 查找 顺序查找 最简单的查找方式,遍历,然后比较 bool search1(int *a,int n,int k){for (int i1;i<n;i){//遍…...
【前端素材】推荐优质后台管理系统Qovex平台模板(附源码)
一、需求分析 1、定义 后台管理系统是一种用于管理和监控网站、应用程序或系统的在线工具。它通常是通过网页界面进行访问和操作,用于管理网站内容、用户权限、数据分析等。后台管理系统是网站或应用程序的控制中心,管理员可以通过后台系统进行各种管理…...
MATLAB环境下基于短时傅里叶变换和Rényi熵的脑电信号和语音信号分析
傅里叶变换是不能很好的反映信号在时域的某一个局部范围的频谱特点的,这一点很可惜。因为在许多实际工程中,人们对信号在局部区域的特征是比较关心的,这些特征包含着十分有用的信息。这类信号因为在时域(或者是空间域)上具有突变的非稳定性和…...
Go语言调用身份证实名认证API方法-标准版身份证实名认证接口
翔云身份证实名认证接口具备高准确度的身份信息比对能力,包括姓名、身份证号码、人脸照片等信息的一致性验证,并能实时反馈验证结果。 以下是GO语言调用翔云身份实名认证API的代码: package mainimport ("fmt""bytes"&q…...
数据库增删改查
DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)DML: 数据操作语言,用来对数据库表中的数据进行增删改DQL: 数据查询语言,用来查询数据库中表的记录DCL: 数据控制语言,用来创建数据库用户、控制数…...
10.CSS3的calc函数
CSS3 的 calc 函数 经典真题 CSS 的计算属性知道吗? CSS3 中的 calc 函数 calc 是英文单词 calculate(计算)的缩写,是 CSS3 的一个新增的功能。 MDN 的解释为可以用在任何长度、数值、时间、角度、频率等处,语法如…...
echrts 全国地图、各省市地图json文件下载
DataV.GeoAtlas地理小工具系列...
如何使用1688.item_search_shop API获取阿里巴巴店铺商品信息
要使用1688的item_search_shop API获取阿里巴巴店铺的商品信息,你通常需要遵循以下步骤: 1. 注册并获取API密钥 首先,你需要在阿里巴巴开放平台(如1688开放平台)上注册一个开发者账号,并创建一个应用。创…...
PLC_博图系列☞基本指令“取反RLO”
PLC_博图系列☞基本指令“取反RLO” 文章目录 PLC_博图系列☞基本指令“取反RLO”背景介绍取反RLO说明示例 关键字: PLC、 西门子、 博图、 Siemens 、 取反RLO 背景介绍 这是一篇关于PLC编程的文章,特别是关于西门子的博图软件。我并不是专业的PLC…...
docker安装PostGIS扩展
去docker仓库查找你想要安装的镜像版本,并pull下来 我下载的版本: [rootlocalhost ~]# docker pull postgis/postgis:12-3.2运行容器 [rootlocalhost ~]# docker run --name postgis --privilegedtrue --restartalways -e POSTGRES_USER12345678 -e P…...
LabVIEW开发FPGA的高速并行视觉检测系统
LabVIEW开发FPGA的高速并行视觉检测系统 随着智能制造的发展,视觉检测在生产线中扮演着越来越重要的角色,尤其是在质量控制方面。传统的基于PLC的视觉检测系统受限于处理速度和准确性,难以满足当前生产需求的高速和高精度要求。为此…...
P5734 【深基6.例6】文字处理软件 - Java
题目描述 你需要开发一款文字处理软件。最开始时输入一个字符串作为初始文档。可以认为文档开头是第 00 个字符。需要支持以下操作: 1 str:后接插入,在文档后面插入字符串 strstr,并输出文档的字符串;2 a bÿ…...
关于设备连接有人云的使用及modbus rtu协议,服务器端TCP调试设置
有人云调试 调试过程问题1. 关于modbus rtu协议,实质上有三种modbus基本原理modbus 格式2. 关于modbus crc16通信校验3. 关于在ubuntu阿里云服务器端,监听网络数据之调试mNetAssist4. 使用有人FAE传给的设置软件问题???之前的一个项目,再拿出来回顾下。 调试过程 先 要在有…...
开源图表库Echarts 简介与基本使用
ECharts 是一个使用 JavaScript 实现的开源可视化图表库,由百度团队开发。它提供了丰富的图表类型,如折线图、柱状图、饼图、地图、雷达图等,并且可以轻松地与其他前端框架和库集成。ECharts 的设计目的是为了满足复杂数据的可视化需求&#…...
变更ip后怎么查现在的代理ip地址?代理IP在网络请求中有哪些优势?
要查看当前的代理IP地址,可以尝试以下方法 浏览器设置:在大部分浏览器中,可以通过菜单选项中的“设置”或“帮助”来查找关于代理服务器的设置。在这里,可以看到当前使用的代理服务器地址、端口号以及是否启用了代理服务。在线工具…...
C#浮点运算出错问题
在计算单价等活动的时候,我们经常会用到double 浮点进行运算,但是在乘除的时候经常出现精度丢失问题 decimal 关键字表示 128 位数据类型。 同浮点型相比,decimal 类型具有更高的精度和更小的范围,这使它适合于财务和货币计算 dou…...
WPF 控件禁用时,显示悬浮提示
WPF 控件禁用时,显示悬浮提示 控件在禁用状态下,按钮是没有悬浮提示信息的,是事件触发的机制; 如果要禁用下也有悬浮提示,可以在控件外面加一层,例如: <Border Grid.Column"1" To…...
在 Windows 上使用 VC++ 编译 OpenSSL 源码的步骤
在 Windows 上使用 VC 编译 OpenSSL 源码的步骤如下: 准备工作 安装 Visual Studio 2017 或更高版本。安装 Perl 脚本解释器。安装 NASM 汇编器。 编译步骤 下载 OpenSSL 源码。解压 OpenSSL 源码。打开命令行工具,并进入 OpenSSL 源码目录。运行以下…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
