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

相关文章

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实