在研究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的使用
运行结果:
重点说明...(不是省略号),就是一个所谓的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,模拟实现代码:
运行结果
第一行 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<>{},结束递归
用类继承的方式展示如下图:
数据在内存中的表现形式如下图:
注意:
递归调用处理的都是参数,使用function template
递归继承处理的是类型,使用class template
初始化的过程是递归调用Mytuple的第二个构造函数,使用inherited调用基类中的构造函数,依次类推。