Modern C++ std::get<n>(tuple)的原理

2024-02-01 04:04
文章标签 c++ 原理 std get modern tuple

本文主要是介绍Modern C++ std::get<n>(tuple)的原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 前言

前面我们讲过std::tuple的实现原理,但没有讲如何取出数据,本节着重讲讲这点。本节与之前的blog有较大关联,如果您没看,这里有链接,链接已按由浅入深排好序,您可以按顺序阅读。如果时间少可以直接看第三篇由工具快速理解std::tuple的实现原理:

  1. Modern C++ std::unique_ptr的实现原理 带出size问题
  2. Modern C++ std::tuple的size 编程实验size问题
  3. Modern C++利用工具快速理解std::tuple的实现原理 快速理解std::tuple的实现原理
  4. GDB调试技巧实战–自动化画出类关系图 写一个普世工具结合GDB自动画类关系图,当然也适用std::tuple
  5. Modern C++ sizeof(std::tuple)的秘密及实现代码解读 从源码理解std::tuple的实现

2. 按图索骥

原理也不难,根据要取的数据是空类还是非空类分两种情况,先上图,懂了就不必往下看了。

请添加图片描述
实验代码贴在这,方便大家从copy试验:

#include<iostream>
#include <tuple>
using namespace std;struct Empty{constexpr Empty() noexcept = default;
};std::tuple<int,Empty,Empty,int> ie2i = {1, Empty(), Empty(), 2};//12auto& ie2i_0 = std::get<0>(ie2i);auto& ie2i_1 = std::get<1>(ie2i);auto& ie2i_2 = std::get<2>(ie2i);auto& ie2i_3 = std::get<3>(ie2i);std::cout<<"sizeof(std::tuple<int,Empty,Empty,int>):"<<sizeof(std::tuple<int,Empty,Empty,int>)<<std::endl;std::cout<<"ie2i addr:"<<&ie2i<<" ie2i_3:"<<&ie2i_3<<" ie2i_2:"<<&ie2i_2<<" ie2i_1:"<<&ie2i_1<<" ie2i_0:"<<&ie2i_0<<std::endl<<std::endl;

3. 看代码实现

3.1 先看取第一个元素:类型为int,值为1

在这里插入图片描述
注意下面由__t转换为__b, 即从类型std::_Tuple_impl<0, int, Empty, Empty, int> &转成了std::_Head_base<0, int, false> &,而且偏移加了8,说明在std::tuple<int,Empty, Empty, int>这个大房子里std::_Head_base<0, int, false> 位于+8处的偏房中。偏移大小和对象内存模型相关,我们不去讨论。
在这里插入图片描述

3.2 再看取第二个元素:类型为Empty:

在这里插入图片描述
地址从d4f0跳到了d4f4, 说明在std::tuple<int,Empty, Empty, int>这个大房子里std::_Head_base<1, Empty, true> 位于+4处的偏房中, 这一点可以由下面的反汇编代码证明():
在这里插入图片描述
$rax偷偷加了4传给了_M_head(_Head_base& __b)

/usr/include/c++/8/tuple72   template<std::size_t _Idx, typename _Head>73     struct _Head_base<_Idx, _Head, true>74     : public _Head75     {
... ...112       static constexpr _Head&113       _M_head(_Head_base& __b) noexcept { return __b; }

这篇关于Modern C++ std::get<n>(tuple)的原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/666021

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

SpringBoot中Get请求和POST请求接收参数示例详解

《SpringBoot中Get请求和POST请求接收参数示例详解》文章详细介绍了SpringBoot中Get请求和POST请求的参数接收方式,包括方法形参接收参数、实体类接收参数、HttpServle... 目录1、Get请求1.1 方法形参接收参数 这种方式一般适用参数比较少的情况,并且前后端参数名称必须

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象