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 源码目录。运行以下…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...
Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...
C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...
