traits编程技法大量运用于STL实现中。通过它在一定程度上弥补了C++不是强型别语言的遗憾,增强了C++关于型别认证方面的能力。

traits编程技法是利用“内嵌型别”的编程技法和编译器的template参数推导功能实现的。

iterator_traits

1.对于class type要求其“内嵌型别”

要求与STL兼容的容器,其迭代器必须定义一下五种型别:

iterator_category  迭代器类型

value_type  迭代器所指对象类型

difference_type  迭代器间的距离类型

pointer

reference

2.对于非class type(如:原生指针)需要使用template partial specialization(偏特化)

 //class type的“内嵌型别”
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 _Tp>
struct iterator_traits<_Tp*> {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
}; //对const指针的偏特化
template <class _Tp>
struct iterator_traits<const _Tp*> {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};

iterator中为什么要引入traits机制?

提高效率

对效率的至极追求贯穿整个STL设计,traits机制的引入是为了实现 同一方法用于不同类型时调用对该类型最高效的版本 以提高效率。

例如 advance():

 //用于input_iterator的版本
template <class _InputIter, class _Distance>
inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
while (__n--) ++__i;
} //用于 bidirectional_iterator的版本
template <class _BidirectionalIterator, class _Distance>
inline void __advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag) {
__STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator);
if (__n >= )
while (__n--) ++__i;
else
while (__n++) --__i;
} //用于 random_access_iterator的版本
template <class _RandomAccessIterator, class _Distance>
inline void __advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag) {
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
__i += __n;
} //advance方法的对外接口
template <class _InputIterator, class _Distance>
inline void advance(_InputIterator& __i, _Distance __n) {
__STL_REQUIRES(_InputIterator, _InputIterator);
__advance(__i, __n, iterator_category(__i));
}

SGI STL中迭代器之外的 __type_traits

STL只对迭代器进行了traits规范,制定类iterator_traits。SGI 把这种规范扩大到类迭代器之外,也就是__type_traits(__前缀表示是SGI 内部使用的,不在STL规范内)。

iterator_traits负责萃取iterator特性,而__type_traits则负责萃取一下五种型别(type)特性:

  has_trivial_default_constructor  是否有平凡的默认构造函数

  has_trivial_copy_constructor  是否有平凡的拷贝构造函数

  has_trivial_assignment_operator  是否有平凡的分配操作

  has_trivial_destructor  是否有平凡的析构函数

  is_POD_type  是否为POD类型(POD:Plain Old Data

如果class内含指针成员,并对它进行内存动态分配,那么这个class就需要实现自己的 non-trivial-xxx。

上述特性应该响应我们“真”或“假”,但却不能是bool值,因为我们要利用其响应来进行参数推导,而编译器只有面对class object形式的参数时才能进行参数推导,因此响应应该是带有“真”“假”性质的不同类。SGI STL中如下定义:

1 struct __true_type {
2 };
3
4 struct __false_type {
5 };
 template <class _Tp>
struct __type_traits {
typedef __true_type this_dummy_member_must_be_first;
/* Do not remove this member. It informs a compiler which
automatically specializes __type_traits that this
__type_traits template is special. It just makes sure that
things work if an implementation is using a template
called __type_traits for something unrelated. */ /* The following restrictions should be observed for the sake of
compilers which automatically produce type specific specializations
of this class:
- You may reorder the members below if you wish
- You may remove any of the members below if you wish
- You must not rename members without making the corresponding
name change in the compiler
- Members you add will be treated like regular members unless
you add the appropriate support in the compiler. */ 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

在SGI STL的Type_traits.h中对C++ 内建的bool/char/signed char/unsigned char等标记为__true_type。

为什么要引入__type_triats?

答案还是提高效率

对于标记为__true_type的型别,对其对象进行构造/析构/拷贝/赋值等操作时就可以采用最有效率的措施。(如:不必调用高层次的constructor/destructor,而采用内存直接处理操作malloc()/memcpy()等)

STL Traits编程技法的更多相关文章

  1. STL源码--iterator和traits编程技法

    第一部分 iterator学习 STL iterators定义: 提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式. 任何iteartor都应该提供5 ...

  2. STL源码分析读书笔记--第三章--迭代器(iterator)概念与traits编程技法

    1.准备知识 typename用法 用法1:等效于模板编程中的class 用法2:用于显式地告诉编译器接下来的名称是类型名,对于这个区分,下面的参考链接中说得好,如果编译器不知道 T::bar 是类型 ...

  3. STL中的Traits编程技法

    最近在看读<STL源码剖析>,看到Traits编程技法这节时,不禁感慨STL源码作者的创新能力.那么什么是Traits编程技法呢?且听我娓娓道来: 我们知道容器的许多操作都是通过迭代器展开 ...

  4. STL——迭代器与traits编程技法

    一.迭代器 1. 迭代器设计思维——STL关键所在 在<Design Patterns>一书中对iterator模式定义如下:提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素 ...

  5. STL源码之traits编程技法

    摘要 主要讨论如何获取迭代器相应型别.使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决.方法如下: function template的参数推导机制 例如: tem ...

  6. STL源码剖析——iterators与trait编程#2 Traits编程技法

    在算法中运用迭代器时,很可能用到其相应类型.什么是相应类型?迭代器所指对象的类型便是其中一个.我曾有一个错误的理解,那就是认为相应类型就是迭代器所指对象的类型,其实不然,相应类型是一个大的类别,迭代器 ...

  7. STL之traits编程技法

    traits编程技法利用了“内嵌型别”的编程技巧与编译器的template参数推导功能. 下面主要看看利用traits编程技法实现的迭代器萃取机制. 5种迭代器类型定义: struct input_i ...

  8. 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...

  9. [转]Traits 编程技法+模板偏特化+template参数推导+内嵌型别编程技巧

    STL中,traits编程技法得到了很大的应用,了解这个,才能一窥STL奥妙所在. 先将自己所理解的记录如下: Traits技术可以用来获得一个 类型 的相关信息的. 首先假如有以下一个泛型的迭代器类 ...

随机推荐

  1. PowerDesigner自定义列和过滤器

    好多次要增加注释列,默认值列都忘了怎么设置,写下来以备后用:) 选中表,然后右键,选择properties->columns->点击下图中那个不显眼的小图标(Customize Colum ...

  2. 描述cookie,sessionstroage,localstrage的区别

    HTML5 提供了两种在客户端存储数据的新方法(Web Storage): localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 ...

  3. 谷歌chrome浏览器桌面提醒 webkitNotifications

    原创: //点击时开启提醒 $(".message_alert").toggle(function(){ $(".message_alert_tip").htm ...

  4. 琐碎-hadoop1.X和2.X的区别

    1.  jobtracker做了分离,分成了resourceManager和nodemanager: 2.  MR变成了和HBase和Hive等一样的yarn上面的一个应用: 3.  1.x的默认块大 ...

  5. iOS,面试必看,最全梳理

    序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态 ...

  6. 1002 GTY's birthday gift

    GTY's birthday gift                                                                       Time Limit ...

  7. c++之函数原型

    函数原型: [作用域] [函数连接规范] 返回值类型 [函数调用规范] 函数名 (类型1[形参1]...); 函数定义: [函数连接规范] 返回值类型 [函数调用规范] 函数名 (形参列表) {... ...

  8. Android(java)学习笔记95:Android原理揭秘系列之View、ViewGroup

    作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器, ...

  9. vs中两张图片的融合

    这个其实就是从csdn上面下载的一个例程.感谢这位同学的总结,与源码的有偿分享. 本随笔就是把它通过4个随笔的拆分,实现的. 可以通过: http://blog.csdn.net/masibuaa/a ...

  10. hdu3584 树状数组

    思路:从一维扩展到三维.可以看看poj2155的解法. #include<iostream> #include<cstring> #include<algorithm&g ...