当前位置: 首页 > news >正文

Modern C++ std::visit从实践到原理

前言

std::visit 是 C++17 中引入的一个模板函数,它用于对给定的 variantunion 类型或任何其他兼容的类型执行一个访问者操作。这个函数为多种可能类型的值提供了一种统一的访问机制。使用 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 中引入的一个模板函数&#xff0c;它用于对给定的 variant、union 类型或任何其他兼容的类型执行一个访问者操作。这个函数为多种可能类型的值提供了一种统一的访问机制。使用 std::visit&#xff0c;你可以编写更通用和灵活的代码&#xff0c;而无需关…...

谷歌gemma2b windows本地cpu gpu部署,pytorch框架,模型文件百度网盘下载

简介 谷歌DeepMind发布了Gemma,这是一系列灵感来自用于Gemini相同研究和技术的开放模型。开放模型适用于各种用例,这是谷歌非常明智的举措。有2B(在2T tokens上训练)和7B(在6T tokens上训练)模型,包括基础和指令调整版本。在8192个token的上下文长度上进行训练。允许商业使…...

数据结构-查找与排序

数据结构再往后就是比较零散的各种操作&#xff0c;查找与排序是其中最常出现的&#xff0c;今天来总结一下常用的查找与排序所用的方法 查找 顺序查找 最简单的查找方式&#xff0c;遍历&#xff0c;然后比较 bool search1(int *a,int n,int k){for (int i1;i<n;i){//遍…...

【前端素材】推荐优质后台管理系统Qovex平台模板(附源码)

一、需求分析 1、定义 后台管理系统是一种用于管理和监控网站、应用程序或系统的在线工具。它通常是通过网页界面进行访问和操作&#xff0c;用于管理网站内容、用户权限、数据分析等。后台管理系统是网站或应用程序的控制中心&#xff0c;管理员可以通过后台系统进行各种管理…...

MATLAB环境下基于短时傅里叶变换和Rényi熵的脑电信号和语音信号分析

傅里叶变换是不能很好的反映信号在时域的某一个局部范围的频谱特点的&#xff0c;这一点很可惜。因为在许多实际工程中&#xff0c;人们对信号在局部区域的特征是比较关心的&#xff0c;这些特征包含着十分有用的信息。这类信号因为在时域(或者是空间域)上具有突变的非稳定性和…...

Go语言调用身份证实名认证API方法-标准版身份证实名认证接口

翔云身份证实名认证接口具备高准确度的身份信息比对能力&#xff0c;包括姓名、身份证号码、人脸照片等信息的一致性验证&#xff0c;并能实时反馈验证结果。 以下是GO语言调用翔云身份实名认证API的代码&#xff1a; package mainimport ("fmt""bytes"&q…...

数据库增删改查

DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用来创建数据库用户、控制数…...

10.CSS3的calc函数

CSS3 的 calc 函数 经典真题 CSS 的计算属性知道吗&#xff1f; CSS3 中的 calc 函数 calc 是英文单词 calculate&#xff08;计算&#xff09;的缩写&#xff0c;是 CSS3 的一个新增的功能。 MDN 的解释为可以用在任何长度、数值、时间、角度、频率等处&#xff0c;语法如…...

echrts 全国地图、各省市地图json文件下载

DataV.GeoAtlas地理小工具系列...

如何使用1688.item_search_shop API获取阿里巴巴店铺商品信息

要使用1688的item_search_shop API获取阿里巴巴店铺的商品信息&#xff0c;你通常需要遵循以下步骤&#xff1a; 1. 注册并获取API密钥 首先&#xff0c;你需要在阿里巴巴开放平台&#xff08;如1688开放平台&#xff09;上注册一个开发者账号&#xff0c;并创建一个应用。创…...

PLC_博图系列☞基本指令“取反RLO”

PLC_博图系列☞基本指令“取反RLO” 文章目录 PLC_博图系列☞基本指令“取反RLO”背景介绍取反RLO说明示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 取反RLO 背景介绍 这是一篇关于PLC编程的文章&#xff0c;特别是关于西门子的博图软件。我并不是专业的PLC…...

docker安装PostGIS扩展

去docker仓库查找你想要安装的镜像版本&#xff0c;并pull下来 我下载的版本&#xff1a; [rootlocalhost ~]# docker pull postgis/postgis:12-3.2运行容器 [rootlocalhost ~]# docker run --name postgis --privilegedtrue --restartalways -e POSTGRES_USER12345678 -e P…...

LabVIEW开发FPGA的高速并行视觉检测系统

LabVIEW开发FPGA的高速并行视觉检测系统 随着智能制造的发展&#xff0c;视觉检测在生产线中扮演着越来越重要的角色&#xff0c;尤其是在质量控制方面。传统的基于PLC的视觉检测系统受限于处理速度和准确性&#xff0c;难以满足当前生产需求的高速和高精度要求。为此&#xf…...

P5734 【深基6.例6】文字处理软件 - Java

题目描述 你需要开发一款文字处理软件。最开始时输入一个字符串作为初始文档。可以认为文档开头是第 00 个字符。需要支持以下操作&#xff1a; 1 str&#xff1a;后接插入&#xff0c;在文档后面插入字符串 strstr&#xff0c;并输出文档的字符串&#xff1b;2 a b&#xff…...

关于设备连接有人云的使用及modbus rtu协议,服务器端TCP调试设置

有人云调试 调试过程问题1. 关于modbus rtu协议,实质上有三种modbus基本原理modbus 格式2. 关于modbus crc16通信校验3. 关于在ubuntu阿里云服务器端,监听网络数据之调试mNetAssist4. 使用有人FAE传给的设置软件问题???之前的一个项目,再拿出来回顾下。 调试过程 先 要在有…...

开源图表库Echarts 简介与基本使用

ECharts 是一个使用 JavaScript 实现的开源可视化图表库&#xff0c;由百度团队开发。它提供了丰富的图表类型&#xff0c;如折线图、柱状图、饼图、地图、雷达图等&#xff0c;并且可以轻松地与其他前端框架和库集成。ECharts 的设计目的是为了满足复杂数据的可视化需求&#…...

变更ip后怎么查现在的代理ip地址?代理IP在网络请求中有哪些优势?

要查看当前的代理IP地址&#xff0c;可以尝试以下方法 浏览器设置&#xff1a;在大部分浏览器中&#xff0c;可以通过菜单选项中的“设置”或“帮助”来查找关于代理服务器的设置。在这里&#xff0c;可以看到当前使用的代理服务器地址、端口号以及是否启用了代理服务。在线工具…...

C#浮点运算出错问题

在计算单价等活动的时候&#xff0c;我们经常会用到double 浮点进行运算&#xff0c;但是在乘除的时候经常出现精度丢失问题 decimal 关键字表示 128 位数据类型。 同浮点型相比&#xff0c;decimal 类型具有更高的精度和更小的范围&#xff0c;这使它适合于财务和货币计算 dou…...

WPF 控件禁用时,显示悬浮提示

WPF 控件禁用时&#xff0c;显示悬浮提示 控件在禁用状态下&#xff0c;按钮是没有悬浮提示信息的&#xff0c;是事件触发的机制&#xff1b; 如果要禁用下也有悬浮提示&#xff0c;可以在控件外面加一层&#xff0c;例如&#xff1a; <Border Grid.Column"1" To…...

在 Windows 上使用 VC++ 编译 OpenSSL 源码的步骤

在 Windows 上使用 VC 编译 OpenSSL 源码的步骤如下&#xff1a; 准备工作 安装 Visual Studio 2017 或更高版本。安装 Perl 脚本解释器。安装 NASM 汇编器。 编译步骤 下载 OpenSSL 源码。解压 OpenSSL 源码。打开命令行工具&#xff0c;并进入 OpenSSL 源码目录。运行以下…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...

SQL进阶之旅 Day 22:批处理与游标优化

【SQL进阶之旅 Day 22】批处理与游标优化 文章简述&#xff08;300字左右&#xff09; 在数据库开发中&#xff0c;面对大量数据的处理任务时&#xff0c;单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”&#xff0c;深入探讨如何通过批量操作和游标技术提…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...