问题: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的实现是这样的)