zoukankan      html  css  js  c++  java
  • boost源码解析之tuple

    tuple是Boost库里面的可变长参数的实现(现已被纳入c++11标准)。
    本篇源码解析是基于boost 1.60版本源码。
    源码相对路径为:"boost/tuple/tuple_basic.hpp"

    首先我们来看下tuple的源码实现摘要简化版本,如下:

    template <class T0, class T1, class T2, class T3, class T4,
              class T5, class T6, class T7, class T8, class T9>
    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;
    //构造函数重载,分别重载0~10个参数 tuple() {} //access_traits<T0>::parameter_type,查看定义实际为const boost::remove_cv<T>::type&,即去除cv限定符的const引用类型 //源码参见"boost/type_traits/remove_cv.hpp" tuple(typename access_traits<T0>::parameter_type t0) : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),//detail::cnull实际为空结构null_type detail::cnull(), detail::cnull(), detail::cnull(),detail::cnull(), detail::cnull(), detail::cnull()) {} //根据上面的解释简化一下 tuple(const T0 & t0, const T1 & t1) : inherited(t0, t1, null_type(), null_type(),null_type(), null_type(), null_type(), null_type(),null_type(), null_type() ){} //此处省去N个构造函数 tuple(const T0 & t0, const T1 t1, const& T2 t2, const T3 & t3, const T4 & t4, const T5 & t5, const T6 & t6, const T7 & t7, const T8 & t8,const T9 & t9) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {} //... } };

    从上我们即可知道tuple构造函数支持可变长度(0~10个)的参数。但是具体的实现结构map_tuple_to_cons类型,
    我们还不清楚,那接着我们一起看一下。

    template <class T0, class T1, class T2, class T3, class T4,
              class T5, class T6, class T7, class T8, class T9>
    struct map_tuple_to_cons
    {
      typedef
      cons< T0,typename map_tuple_to_cons<T1, T2, T3, T4, T5,T6, T7, T8, T9, null_type>::type > type;
    };

    不难看出,map_tuple_to_cons是一个递归的结构。具体的实现是cons,我们来看下cons的源码摘要:

    template <class HT, class TT>
    struct cons {
      typedef HT head_type;//成员类型 头元素
      typedef TT tail_type;//成员类型 尾元素
    
      typedef typename detail::wrap_non_storeable_type<head_type>::type stored_head_type;
    
      stored_head_type head; //头元素
      tail_type tail; //尾元素
    
      //分别重载了get_head和get_tail的non-const和const的版本
      typename access_traits<stored_head_type>::non_const_type
      get_head() { return head; }
     
      typename access_traits<stored_head_type>::const_type
      get_head() const { return head; }
    
      typename access_traits<tail_type>::non_const_type
      get_tail() { return tail; }
    
      typename access_traits<tail_type>::const_type
      get_tail() const { return tail; }
    
      cons() : head(), tail() {}
    
      cons(typename access_traits<stored_head_type>::parameter_type h,
           const tail_type& t) : head (h), tail(t) {}
    
      template <class T1, class T2, class T3, class T4, class T5,
                class T6, class T7, class T8, class T9, class T10>
      cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
            T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
        : head (t1),
          tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull()) {}
         
      //此处省去部分不关心的代码...
     
      // get member functions (non-const and const)
      template <int N>
      typename access_traits< typename element<N, cons<HT, TT> >::type >::non_const_type
      get() {
        return boost::tuples::get<N>(*this); // delegate to non-member get
      }
    
      template <int N>
      typename access_traits< typename element<N, cons<HT, TT> >::type >::const_type
      get() const {
        return boost::tuples::get<N>(*this); // delegate to non-member get
      }
    };

    另外,boost库还提供可tuple的辅助函数make_tuple,支持生成返回带0~10个参数版本的tuple,比较简单,不细讲。

    下面通过代码演示一下,tuple的基本使用。

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include "boost/tuple/tuple.hpp"
    
    using namespace std;
    using namespace boost;
    
    int main()
    {    
         int id = 1;
         string name="liu";
         int age = 30;
        
         tuple<int, string, int > tp( id, name,  age);
         //可以通过make_tuple函数来构造tuple
         tuple<int,string,int> tp1 = make_tuple( id, name, age);
        
         //get方法的具体实现,有兴趣的可以看下,递归获取。
         cout << tp.get<0>()  << "," << tp.get<1>()  << "," << tp.get<2>() << endl;
         cout << tp.head << endl;
        
         //验证刚才讲的递归结构
         tuple< string , int> sub_tp = tp.tail;
         cout << sub_tp.head << ","  << endl;
        
         tp.get<0>() = 2;//返回
        
         //注意此种情况下id的值不会改变,tuple构造函数第一个类型为const int &类型,见tuple源码摘要
         cout << id << "==>" << tp.get<0>() << endl;
    
         return 0;
    }
  • 相关阅读:
    递归初级——第39级台阶
    排序——快速排序(尾递归优化)
    排序——快速排序(优化小数组时的排序方案 )
    排序——快速排序(三数取中法和优化不必要交换)
    排序——归并排序(递归实现+迭代实现 )
    超详细Hexo+Github博客搭建小白教程
    每日算法系列【LeetCode 1031】两个非重叠子数组的最大和
    每日算法系列【LeetCode 330】按要求补齐数组
    5W2H | 关于写博客的七点反思
    每日算法系列【LeetCode 124】二叉树中的最大路径和
  • 原文地址:https://www.cnblogs.com/chuyongliu/p/5326951.html
Copyright © 2011-2022 走看看