美文网首页
C++ Traits

C++ Traits

作者: 虚空寂静 | 来源:发表于2018-08-07 11:19 被阅读0次

    STL 偏特化设计

    概念:如果class template 中存在一个或者多个template参数,可以针对其中某个或者几个,但不是全部的template参数进行特化工作。
    
    1. 迭代器型别 value_type,指的是迭代器所指的对象的型别
      typedef T value_type
    2. difference_type 表示两个迭代器之间的距离,可以用来表示一个容器的最大容量(连续空间上,头尾之间的距离),stl中的count(),表示的结果就是difference_type
      typedef typename T::difference_type difference_type 一般情况
      typedef ptrdiff_t difference_type 原生指针
      //任何时候需要任何迭代器I 的difference_type 可以写成
      typename iterator_traits<I>::difference_type
      
    3. reference type 引用类型
      typedef T& reference;
    4. pointer type 指针类型
      typedef T& pointer;
    5. iterator_category; 标记类型
      typedef xxx_iterator_tag iterator_category;

    例如:

    template <class Iterator>
    struct iterator_traits {
      typedef typename Iterator::iterator_category iterator_category;
      typedef typename Iterator::value_type        value_type;
      typedef typename Iterator::difference_type   difference_type;
      typedef typename Iterator::pointer           pointer;
      typedef typename Iterator::reference         reference;
    };
    

    注意点:

    • 设计了五个标签:
      struct input_iterator_tag {}; //只读
      struct output_iterator_tag {}; //只写
      struct forward_iterator_tag : public input_iterator_tag {}; // 可读写
      struct bidirectional_iterator_tag : public forward_iterator_tag {}; // 双向移动
      struct random_access_iterator_tag : public bidirectional_iterator_tag {}; // 随机读写,即是所有可操作行为

    • 标签用来标记重载函数特征例如

       template <class InputIterator, class Distance>
       inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
        //逐一前进
         while (n--) ++i;
       }
       template <class BidirectionalIterator, class Distance>
       inline void __advance(BidirectionalIterator& i, Distance n, 
       bidirectional_iterator_tag) {
       if (n >= 0)
       while (n--) ++i;
         else
       while (n++) --i;
       }
      
       template <class RandomAccessIterator, class Distance>
       inline void __advance(RandomAccessIterator& i, Distance n, 
                             random_access_iterator_tag) {
         i += n;
       }
      

      以及计算两个迭代器的distance()函数

    • 以上两者诠释了迭代器分为五类的设计与应用,利用iterator_traits,将迭代器萃取出来,结果就是讲类似的进行标记,然后通过各个iterator_traits形式通过内嵌的类型,和template进行参数推导,尤其是iterator_category等提取验证

    • taits,通过将类型等信息声明为局部变量,对外接口func,实际操作有funcImpl执行,根据funcImpl的参数类型进行推导,没有返回值的易于理解处理,可以直接通过参数个数,参数诶下进行处理 模板参数类型推导

        template<typename Iterator>
        typename Iterator::value_type  //返回类型
        function(Iterator iter)
        {
        return *iter;
        }
         
        //通过iterator_traits作用后的版本
        template<typename Iterator>
        typename iterator_traits<Iterator>::value_type  //返回类型
        function(Iterator iter)
        { 
        return *iter;
        }  
    
    

    利用typename告诉编译器这是个类型,保证编译顺利,指针没办法进行定义内嵌的类型(value_type等)通过特化处理,就是直接将<T*>进行替代<T>进行特化处理

    • 继承迭代处理
        template <typename T>
        class ListIter : public std::iterator<std::forward_iterator_tag, T>
        {
            
        }
    

    标记登记

    1. 标记目标函数(一般模板)具备的特性,返回类型,传入类型类别
    2. 登记目标函数(特化模板)传入参数的特征,返回特征,返回标记

    template <class type>
    struct __type_traits { 
       typedef __true_type     this_dummy_member_must_be_first;
       typedef __false_type    has_trivial_default_constructor;
       typedef __false_type    has_trivial_copy_constructor;
       typedef __false_type    has_trivial_assignment_operator;
       typedef __false_type    has_trivial_destructor;
       typedef __false_type    is_POD_type;
    };
    

    has_trivial_xxx:判断准则:class内含指针成员,并且对改成员进行了内存动态配置,分配的操作类型判定has_trivial_xxx

    相关文章

      网友评论

          本文标题:C++ Traits

          本文链接:https://www.haomeiwen.com/subject/ipuovftx.html