STL(七)之萃取技术

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;
};

原文地址:https://www.cnblogs.com/xcb-1024day/p/11332501.html

时间: 2024-10-06 15:54:58

STL(七)之萃取技术的相关文章

STL学习_萃取技术__type_traits

之前在学习STL库中的析构工具destory()时,提到过这样一句话,此函数设法找到元素的数值型别,进而利用__type_traits<>求取适当措施.一直难以理解,现在自己总结了下自己对萃取技术的理解. 让自己困惑的程序: template<class T> void destroy(T *pointer) { pointer->~T(); } template<calss ForwardIterator> void destroy(ForwardIterato

STL源代码分析--萃取编程(traits)技术的实现

1.为什么要出现? 依照默认认定.一个模板给出了一个单一的定义,能够用于用户能够想到的不论什么模板參数!可是对于写模板的人而言,这样的方式并不灵活.特别是遇到模板參数为指针时,若想实现与类型的參量不一样的实例化.就变得不太可能了!也有时.想禁止此种同样的实例化变得不太可能! 故而出现了,Partial Specialization! 同一时候,在使用void*指针时.能够最大限度的共享代码,降低代码的膨胀! 2.它是什么?事实上,就是用户定义的偏特化.用template<>来说明这是一个偏特化

C++_模板类与类型萃取技术

在声明变量,函数,和大多数其他类型实体的时候,C++要求我们使用指定的类型.然而,有许多代码,除了类型不同之外,其余部分看起来都是相同的,比如,下面这个例子: bool IsEqual (int left, int right) {     return left == right; } bool IsEqual (const string& left , const string& right) {     return left == right; } void test() {   

迭代器与萃取技术

看了书和老师的讲解,这里大体说一下自己对迭代器和萃取技术的理解. 迭代器它是C++标准模板库里面的智能指针(smart pointer),由于STL设计时并不是以OOP思想为指导,而是以GP,所以让容器与算法分离实际,这么做的好处是可以让各个模块的设计者无需去关系其他模块的实现,从而专心于自己的模块,所以迭代器是用于连接容器和算法的桥梁. OOP(Object-Oriented programming)//面向对象的程序设计 GP(Generic Programming)//泛型程序设计 作为智

C++之萃取技术(traits)

为什么需要类型萃取 前面我们提到了迭代器,它是一个行为类似于smart pointer之类的东西,主要用于对STL容器中的对象进行访问,而且不暴露容器中的内部结构,而迭代器所指对象的型别称为该迭代器的value type;如果在实际的工程当中我们应该怎么获取STL容器中对象的value type 呢,这里面就需要用到C++中模板的特化了,我们先来看看下面的代码: template <class T> void Func() { cout << "非内置类型" &

STL源码分析--萃取编程(traits)技术的实现

1.为什么要出现? 按照默认认定,一个模板给出了一个单一的定义,可以用于用户可以想到的任何模板参数!但是对于写模板的人而言,这种方式并不灵活,特别是遇到模板参数为指针时,若想实现与类型的参量不一样的实例化,就变得不太可能了!也有时,想禁止此种相同的实例化变得不太可能!故而出现了,Partial Specialization! 同时,在使用void*指针时,可以最大限度的共享代码,减少代码的膨胀! 2.它是什么?其实,就是用户定义的偏特化.用template<>来说明这是一个偏特化,针对任何模板

让我们一起来实现一个完整的内存管理工具(线程,内存池,萃取)

//让我们开始一个完整的内存管理工具的实现吧. ///准备做一个完整的内存管理工具 //涉及线程,内存池,萃取,不仅仅是new跟delete的重载(或者说是函数重载),这是我的一个雏形,大家谁有什么好的指正谢谢提出,一起学习. #include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <list> #include <mal

STL 萃取(Traits)机制剖析

模板特化 在将萃取机制之前,先要说明模板特化 当有两个模板类,一个是通用泛型模板,一个是特殊类型模板,如果创建一个特殊类型的对象,会优先调用特殊的类型模板类,例如: template <typename T> //泛型模板 class MyClass { public: MyClass() { cout << "T MyClass!" << endl; } ~MyClass() { cout << "~T MyClass!&qu

[C++]STL萃取学习

STL萃取学习 一,萃取模板类实现 iterator类:模板常用属性的集合类,其他类只需要集成该类即可.本例为学习就只包括value_type属性. iterator_traits类:属性萃取类. /********************************* * * Author : szyu * * Date : 2017.3.1 * **************************************/ #ifndef __SZYU_ITERATOR__ #define __