在研究C++2.0的tuple时,也细看了一下boost库中的tuple版本(摘自1.69版),源码如下:


所在文件:tuple_basic.hpp
template <
  class T0 = null_type, class T1 = null_type, class T2 = null_type,
  class T3 = null_type, class T4 = null_type, class T5 = null_type,
  class T6 = null_type, class T7 = null_type, class T8 = null_type,
  class T9 = null_type>

class tuple :
  public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
{
public:
  typedef typename
    detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
  typedef typename inherited::head_type head_type;
  typedef typename inherited::tail_type tail_type;


// access_traits<T>::parameter_type takes non-reference types as const T&
  tuple() {}

  explicit tuple(typename access_traits<T0>::parameter_type t0)
    : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
                detail::cnull(), detail::cnull(), detail::cnull(),
                detail::cnull(), detail::cnull(), detail::cnull()) {}

  tuple(typename access_traits<T0>::parameter_type t0,
        typename access_traits<T1>::parameter_type t1)
    : inherited(t0, t1, detail::cnull(), detail::cnull(),
                detail::cnull(), detail::cnull(), detail::cnull(),
                detail::cnull(), detail::cnull(), detail::cnull()) {}

...

  tuple(typename access_traits<T0>::parameter_type t0,
        typename access_traits<T1>::parameter_type t1,
        typename access_traits<T2>::parameter_type t2)


更早的版本出现在 Andrei Alexandrescu 的Modern C++ Design中(摘自第45页),此时的版本还不叫tuple,源码如下:

typedef Typelist<signed char,
    Typelist<short int,
        Typelist<int, Typelist<long int, NullType> > > >
    SignedIntegrals; 

#define TYPELIST_1(T1) Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3) >
#define TYPELIST_4(T1, T2, T3, T4) \
 Typelist<T1, TYPELIST_3(T2, T3, T4) >
...
#define TYPELIST_50(...) ... 

从以上两个版本看,每个版本都有个数限制,如果需要更多的参数,那么就需要不停的增加参数个数。

重磅来袭,C++2.0中Variadic Templates(数量不定的模板参数)实现tuple。

先来看下Variadic Templates的使用

【2】C++2.0(C++11/14)tuple

运行结果:

【2】C++2.0(C++11/14)tuple

重点说明...(不是省略号),就是一个所谓的pack(包)

(1)用于template parameters,就是template parameters pack(模板参数包)
(2)用于function parameter types,就是function parameter types pack(函数参数类型包)
(3)用于function parameters,就是function parameter pack(函数参数包)

说明:printEx每次都打印firstArg,再把arg...作为一个包递归调用printEx的模板参数版本,

当传入的包个数为0时会调用printEx的特化版本结束递归过程。

简单了解一下Variadic Templates的用法后,我们开始学习tuple,模拟实现代码:

【2】C++2.0(C++11/14)tuple

运行结果

第一行 tup.head()输出 5,第二行tup.tail().head()输出6.8,第三行tup.tail().tail().head()输出 apple

在tup初始化时,调用Mytuple的构造函数

1.将参数(5)赋值给m_head,其它参数(6.8,apple)做为一个包递归调用MyTuple的构造函数

2.将参数(6.8)赋值给m_head,其它参数(apple)做为一个包递归调用MyTuple的构造函数

3.将参数(apple)赋值给m_head,此时包中已经没有参数,调用类的特化版本class Mytuple<>{},结束递归

用类继承的方式展示如下图:

【2】C++2.0(C++11/14)tuple
Excel画的,不太好看...

数据在内存中的表现形式如下图:

【2】C++2.0(C++11/14)tuple

注意:

递归调用处理的都是参数,使用function template

递归继承处理的是类型,使用class template

初始化的过程是递归调用Mytuple的第二个构造函数,使用inherited调用基类中的构造函数,依次类推。

相关文章: