STL源码解析之tuple

本文深入探讨了C++标准库中std::tuple的实现原理,通过模板递归继承的层次结构,解释了元素存储顺序及常数时间get()操作的实现。通过自定义mytuple类的实例化过程,验证了元素的实际存储顺序是从右向左。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:struct tuple的实现原理(这个部分之关于模板的,只要模板基础可以,我觉得读懂应该没啥问题,我对模板知识掌握的不够牢固,不能完全确定,就做了个测试来解决)下面是源码中的模板定义和部分实例化。(测试的结论我放代码里面了)

(注:有新的收获会再修改,也欢迎大家一起讨论和指教。改于2019/7/1)

 /**
   * Contains the actual implementation of the @c tuple template, stored
   * as a recursive inheritance hierarchy from the first element (most
   * derived class) to the last (least derived class). The @c Idx
   * parameter gives the 0-based index of the element stored at this
   * point in the hierarchy; we use it to implement a constant-time
   * get() operation.
   */
template<std::size_t _Idx, typename... _Elements>
    struct _Tuple_impl;

  /**
   * Recursive tuple implementation. Here we store the @c Head element
   * and derive from a @c Tuple_impl containing the remaining elements
   * (which contains the @c Tail).
   */
  template<std::size_t _Idx, typename _Head, typename... _Tail>
    struct _Tuple_impl<_Idx, _Head, _Tail...>
    : public _Tuple_impl<_Idx + 1, _Tail...>,
      private _Head_base<_Idx, _Head>
{
}

(在此之前,先说明下,tuple的实现是通过模板的递归继承调用的层次结构,在第一段的说明也有说)在上面一开始的注释中,第一个元素是最多基类,最后一个是最少基类,那么哪个是第一个呢,这次就是要验证这个

#include <tuple>
#include <iostream>
#include <functional>
#include <utility>
#include <typeinfo>
using namespace std;
#define myint(V) V==5?2:3
/**

这部分我是测试命名空间后面为啥可以加宏

根据测试,可以在命名空间加上啥都未define的宏,就是只有一个名称(全字母)
在stl中出现很多这种,目测,很多是用来版本定义的(个人观点)
#define ASD
#define _GLIBCXX_PSEUDO_VISIBILITY(v) ASD
namespace myspace _GLIBCXX_PSEUDO_VISIBILITY(v) {

}
*/
/**
  *测试template<std::size_t _Idx, typename _Head, typename... _Tail>
  *  struct _Tuple_impl<_Idx, _Head, _Tail...>
  * : public _Tuple_impl<_Idx + 1, _Tail...>,
  */
template<typename... Elements>
class mytuple;

static int i = 0;


/*这个是用于最初的类,就是基类,简单来说,就是template<typename... Elements> class mytuple;
上面这个声明的一种特殊情况,即模板参数只有一个的情况,没有这个,
在下面继承模板类中的  :public mytuple<_tail...>会报错,从下面的运行结果,可以看出,这个作为所有mytuple的基类(就是最顶端,最多派生类的那个)
*/
template <typename... _tail>
class mytuple{
public:
    mytuple(){ cout<<"begin"<<endl; }
};
/*
在运行结果中,可以看出,第一个是int类型,就是mytuple<string,int,char,string,int> a(1);中的最后一个,那么可以得出结论,问题中的第一个是指的我们输入的最后一个。
*/
template <typename _first,typename... _tail>
class mytuple<_first, _tail...>
        :public mytuple<_tail...>
{
    template<typename...> friend class mytuple;
    typedef _first head;
   public:
    mytuple(){
        head a;
        cout<<"default constructor: "<<i++;
        cout<<" "<<typeid (a).name()<<endl;
    }
   mytuple(int){
        head a;
        cout<<typeid (a).name()<<" "<<i++<<endl;
    }
};

int main()
{
    mytuple<string,int,char,string,int> a(1);
}

 测试结果:

这样,我们再看源代码,在构造函数中_Idx 的变量,每个基类都是递增的,也就是说,越高层的基类,_Idx值越大,而_tail参数的变量越少。也可以得出另外一个结论,不定参数的获取是通过从右边向左边获取的(至少对tuple的实现是这样的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值