• C++标准库(六)之traits技术


    traits技术

    原理:利用template的参数推导机制获取传入的参数型别。

    template<typename T>
    struct Iter
    {
        typedef T value_type;
        ....
    }
    
    template<typename T>
    typename T::value_type func(T* ite)
    {return *ite;}
    

    这种程度,依旧会遇到一个问题:如果不是一个class type(比如指针,引用),就无法进行正确的参数推导。可以使用模板偏特化来处理这种情形:

    template<typename T>
    struct Iter<T*>
    {
        typename T value_type;
    };
    

    我们需要处理的核心问题:通过traits技术如何获得iterator描述的型别?

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

    同时,iterator_traits必须对传入的型别为pointer和pointer-to-const者设计特化版本。

    template<typename T>
    struct iterator_traits<T*>
    {
        ...
        typedef random_access_iterator_tag iterator_category;
    }
    
    template<typename T>
    struct iterator_traits<const T*>
    {
        ...
        typedef random_access_iretator_tag iterator_category;
    }
    

    型别:

    • value type:描述iterator指向对象的型别。
    • difference type:描述两个iterator之间的距离,默认情况下使用C++内建的ptrdiff_t类型
    • reference type:描述iterator所指向对象的引用
    • pointer type:描述iterator所指向对象的指针
    • iterator_category:描述迭代器的相应性别
      • Input Iterator:只读迭代器
      • Output Iterator:只写迭代器
      • Forward Iterator:读写迭代器
      • Bidirectional Iterator:双向移动迭代器,可读写
      • Random Access Iterator:随机移动迭代器,可读写

    利用重载机制,通过在编译期就为不同版本的迭代器选择不同版本的函数:

    template<typename category,typename T,typename dis=ptrdiff_t,typename poin=T*,typename ref=T&>
    struct iterator
    {
        typedef category iterator_category;
        typedef T value_type;
        typedef dis difference_type;
        typedef poin pointer;
        typedef ref 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 <typename InputIterator,typename Distance>
    inline void __advance(InputIterator& iter,Distance n,input_iterator_tag)
    {
        while(n--)
            ++iter;
    }
    
    template <typename ForwardIterator,typename Distance>
    inline void __advance(ForwardIterator& iter,Distance n,forward_iterator_tag)
    {
        __advance(i,n,input_iterator_tag());
    }
    
    template <typename BidirectionalIterator,typename Distance>
    inline void __advance(BidirectionalIterator& iter,Distance n,bidirectional_iterator_tag)
    {
        if(n > 0)
            while(n--)
                ++iter;
        if(n < 0)
            while(n--)
                --iter;
    }
    
    template <typename RandomAccessIterator,typename Distance>
    inline void __advance(RandomAccessIterator& iter,Distance n,random_access_iterator_tag)
    {
        iter += n;
    }
    

    根据traits机制,需要使用以下 的包装器:

    template <typename InputIterator,typename Distance>
    inline void __advance(InputIterator& iter,Distance n)
    {
        __advance(i,n,iteratir_traits<InputIterator>::iterator_category());
    }
    

    获取型别的函数:

    template<typename Iterator>
    inline typename iterator_traits<Iterator>::iterator_category iteratir_category(const Iterator&)
    {
        typedef typename iterator_traits<Iterator>::iterator_category category;
        return category();
    }
    
    template<typename Iterator>
    inline typename iterator_traits<Iterator>::distance_type* distance_type(const Iterator&)
    {
        return static_cast<typename iterator_traits<Iterator>::distance_type*>(0);
    }
    
    template<typename T>
    inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&)
    {
        return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
    }
    
    

    总结

    设计适当的型别,是迭代器的责任。
    设计适当的迭代器,是容器的责任。

    __type_traits

    traits技术弥补了C++语言本身的不足,但是traits技术不仅存在于Iterator之中,也存在于STL之中。iterator_traits负责萃取迭代器特性,__type_traits则负责萃取型别参数。此处的型别参数是指:这个型别是否具有non-trivial default ctor?是否具有non-trivial copy ctor?是否具有non-travial assignment operator?是否具有non-trravial dctor?如果没有的话,我们可以使用memcpy(),memmove()采取最有效的操作。否则的话,需要根据ctor,copy,dctor等进行复杂的操作。
    可以使用如下类似与iterator_traits的方式:

    __type_traits<T>::has_trivial_default_constructor
    __type_traits<T>::has_trivial_copy_constructor
    __type_traits<T>::has_trivial_assignment_operator
    __type_traits<T>::has_trivial_destructor
    __type_traits<T>::is_POD_type
    
    struct __true_type {};
    struct __false_type {};
    
    template<typename T>
    struct __type_traits
    {
        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; 
    }
    

    STL为所有的内嵌性别定义最保守的值,然后再为体统提供类型(char,long,int,double)等设计适当的特化版本。

    __STL_TEMPLATE_NULL struct __type_traits<bool> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #endif /* __STL_NO_BOOL */
    
    __STL_TEMPLATE_NULL struct __type_traits<char> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<signed char> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned char> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #ifdef __STL_HAS_WCHAR_T
    
    __STL_TEMPLATE_NULL struct __type_traits<wchar_t> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #endif /* __STL_HAS_WCHAR_T */
    
    __STL_TEMPLATE_NULL struct __type_traits<short> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned short> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<int> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned int> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<long> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned long> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #ifdef __STL_LONG_LONG
    
    __STL_TEMPLATE_NULL struct __type_traits<long long> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned long long> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #endif /* __STL_LONG_LONG */
    
    __STL_TEMPLATE_NULL struct __type_traits<float> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<double> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<long double> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
    
    template <class _Tp>
    struct __type_traits<_Tp*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
    
    __STL_TEMPLATE_NULL struct __type_traits<char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<signed char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<unsigned char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<const char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<const signed char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
    __STL_TEMPLATE_NULL struct __type_traits<const unsigned char*> {
       typedef __true_type    has_trivial_default_constructor;
       typedef __true_type    has_trivial_copy_constructor;
       typedef __true_type    has_trivial_assignment_operator;
       typedef __true_type    has_trivial_destructor;
       typedef __true_type    is_POD_type;
    };
    
  • 相关阅读:
    requireJS 简要介绍和完整例子
    SQL 语句递归查询 With AS 查找所有子节点
    ztree的添加、修改、删除及前后台交互
    JQuery-zTree.js使用范例
    CSS3自定义滚动条样式 -webkit-scrollbar
    jQuery插件定义
    JQuery 插件开发
    jQuery操作复选框checkbox技巧总结 ---- 设置选中、取消选中、获取被选中的值、判断是否选中等
    Xml序列化
    wen7安装oracle 11g出现"未找到文件 E:development_toolsdatabaseoracleinstall_ddbhomeowbexternaloc4j_applicationsapplicationsWFMLRSVCApp.ear"
  • 原文地址:https://www.cnblogs.com/ukernel/p/9191170.html
Copyright © 2020-2023  润新知