【STL3】类型萃取Traits

 

类型萃取Traits

1.总述

定义:traits中文意思是特性,它通过提取不同类的共性,使得可以统一处理

技术实现:traits运用显式模板特殊化(模板偏特化,全特化)将代码中因为类型不同而发生变化的片段提取出来,用统一的接口来包装,并通过traits模板类公开的接口间接访问相应的类。

STL Iterator必须提供的五种associated types:迭代器萃取器iterator_traits能够兼容迭代器和一般指针,获取其5个关联类型:iterator_category、value_type、difference_type、pointer和pointer. 在实现上,iterator_traits类使用模板的偏特化,对于一般的迭代器类型,直接取迭代器内部定义的关联类型;对于指针和常量指针进行偏特化,指定关联类型的值.

 

 

2.STL萃取器

STL迭代器萃取器必须提供的5种关联类型如下:

// 针对一般的迭代器类型,直接取迭代器内定义的关联类型
template<class I>
struct iterator_traits {
    typedef typename I::iterator_category 	iterator_category;
    typedef typename I::value_type 			value_type;
    typedef typename I::difference_type 	difference_type;
    typedef typename I::pointer 			pointer;
    typedef typename I::reference 			reference;
};

// 针对指针类型进行特化,指定关联类型的值
template<class T>
struct iterator_traits<T*> {
    typedef random_access_iterator_tag 		iterator_category;
    typedef T 								value_type;
    typedef ptrdiff_t 						difference_type;
    typedef T* pointer;
    typedef T& reference;
};

// 针对指针常量类型进行特化,指定关联类型的值
template<class T>
struct iterator_traits<const T*> {
    typedef random_access_iterator_tag 		iterator_category;
    typedef T 								value_type;		// value_tye被用于创建变量,为灵活起见,取 T 而非 const T 作为 value_type
    typedef ptrdiff_t 						difference_type;
    typedef const T* pointer;
    typedef const T& reference;
};

算法中使用某个类型萃取器示例:

template<typename I,...>
void algorithm(...) {
    typename iterator_traits<I>::value_type v1;
}

 

3.类型萃取器的模拟实现

#include <iostream>
using namespace std;

//类似迭代器模板类
template<class T>
struct MyIter {
    typedef T value_type;
    T* ptr;
    MyIter(T* p = 0) : ptr(p) {    }
    T& operator*() const { return *ptr; }
};

//萃取用的结构体iter_traits
template<class I>
struct iter_traits {
    typedef typename I::value_type value_type;
};
//对于指针的范围偏特化
template<class I>
struct iter_traits<I*> {
    typedef I value_type;//注意,这里的I是I而不是I*,即这里和特化版本对应
};

//利用偏特化的萃取, MyType 萃取出了int
template<class I>
void func_trait(I ite)
{
    typedef iter_traits<I::value_type>::value_type MyType;
    MyType a = **ite;
    cout << a;
}

//普通版本的萃取,MyType萃取出了int*
template<class I>
void func(I ite)
{
    typedef iter_traits<I>::value_type MyType;
    //MyType a = reinterpret_cast<MyType>(**ite);
    MyType a = *ite;
    cout << *ite << endl;
    cout << **ite << endl;
}

int main()
{
    int* a = new int(2);
    MyIter<int*> ite(&a);
    func(ite);
    /*
调用过程如下:
        void func(MyIter<int*> ite){
            typedef iter_traits<I>::value_type   == int*    == MyType
        }
    */

    func_trait(ite);
/*
调用过程如下:
        func_trait(MyIter<int*> ite){
            typedef iter_traits<int*>::value_type == typedef iter_traits<int*>::int == int == MyType
            MyType a = **ite;
        }
*/
    return 0;
}

这里MyIter是个迭代器类模板,模板参数类型为T,main函数中这个T为int*, 那我们定义一个参数为int*的迭代器对象,对这个迭代器取内容就应该是int*,实际上是个指针, 这里定义了一个萃取用的结构体iter_traits,普通版的是做为萃取出int*这个类型,便于作为函数返回值或者是定义变量,偏特化版的用做萃取出int类型.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值