2013-04-21 STL之模板编程技巧

C++编程最重要的一个范型编程,可惜工作中还少用到,不过还好STL源码编程中所以的东西都是模板编程,弥补了这一块的不足,同时也让我学到很多技巧。

1、 迭代器概念与traits编程技法

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;

};

以下为偏特化版

template<class T>

struct iteraotr_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 iteraotr_traits<const T*>

{

typedef random_access_iterator_tag iterator_category;

typedef T value_type;

typedef  ptrdiff_t pointer;

typedef const T* pointer;

typedef const T& reference;

};

一般内置数据类型通过第一种模板就可以实现,但是像原生指针时,有一些部件就没有用了,如value_type,这时就需要使用模板的偏特化的特性,

我理解的偏特化就是程序对一些特定的类型的一些特殊处理,但是这个特殊处理可以省去我们很多事,

以后我们就可以很方便的使用其中的变量。如value_type

typedef typename iterator_traits<Iterator>::value_type  而不用担心iterator到底是什么类型


traits 的编程技法很棒,适度的弥补了C++语言本身的不足,下面来看看另外一种用法,

type_traits

STL 编程时是很注重性能的,所以当stl删除一个对象的时候,会先判断一个对象是否具备non-trivial dtor,

如果答案是否定的,那么stl就可以直接使用malloc、memcpy这些效率极高的函数,而不用去调用哪些没用的构造、析构函数,

但是C++本身并没有类型判断,所以就就可以借助traits的编程技巧。


struct _true_type{};

struct _false_type{};

这两个空白classes没有任何成员,不会带来额外负担,却又能表示真假,

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

};

所有的内嵌类型都被定义成了_false_type,这是定义的保守值。下面我们对每一个标量型别设计适当的_type_traits


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

};

......

这里就不一一列举了

看这个的用法


void temp_test(_false_type){cout<<"_false_type"<<endl;}
void temp_test(_true_type) {cout<<"_true_type"<<endl;}


template<class T>
void func_test(T a)
{
        typedef typename _type_traits<T>::is_POD_type is_POD;
        temp_test(is_POD());
}

class Test

{};

int main()

{

Test temp_a;

int a;

func_test(a);

func_test(temp_a);

}


输出的结果是:

_false_type

_true_type

可以看出,这个用法是很简单的,而且用到其他地方,如STL就用它来判断用构造的和析构的对象是否可以直接memcpy和delete,

可以得到很大的性能。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值