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;
};
刚贴上来的是 G++2.9中关于 iterator_traits 的 source code。
我们知道,iterator 是建立在 container 和 algorithm 间的桥梁,成为 container 和 algorithm 互相之间沟通交流的媒介,比方说,algorithm 希望知道更多关于所传入变量的信息,比方说数据类型,迭代器类型等等,那么 萃取 traits 就显得尤为重要了。
看下面这个小例子
template<typename T>
void myFunction(T& coll) {
for (int i = 0; i < coll.size(); ++i) {
cout<<coll[i]<<endl;
}
}
这个函数很简单,就是希望传入一个 container ,然后把他们的每个值都打印出来,那么我传入 vector<int> , vector<string> 等等,这些都是可以的,这没问题。
但是,如果我希望的到 T 这个 container 中的每个数据的数据类型,怎么办呢? 这就需要 萃取机制了,也就是 iterator_traits 了。
我们在上面这个例子中加入一句:
typedef typename iterator_traits<typename T::iterator>::value_type vt;
首先看这句话,把模板的 container 类型的iterator传入iterator_traits,问 iterator_traits 索要value tyep,并定义为 vt ,以供后面使用,这就完成了萃取。
当然,iterator_traits 不仅可以萃取 这个iterator 的 value type,还可以萃取出 category,difference type,pointer,reference的信息,看最上面的定义就知道了。
这里再说明一下,为什么要用 category 对不同 container 的 iterator进行分类呢(如图)?
using __STD::input_iterator_tag;
using __STD::output_iterator_tag;
using __STD::forward_iterator_tag;
using __STD::bidirectional_iterator_tag;
using __STD::random_access_iterator_tag;
原因很简单,这都是为 algorithm 服务的,因为不同的算法,比方说 move 类型的算法,对于 forward_iterator_tag 类型的container,只能向前move,例如forward_list,而对于 bidirectional_iterator_tag 类型的container,比方说 deque,就可以两头移动,所以需要对此进行分类。
最后,除了 iterator_traits 以外,还可以对很多东西进行萃取,比方说 type traits,char traits,allocator traits,pointer traits,array traits。这里列出 type traits的代码,供大家参考。(G++ 2.9)
template <class _Tp>
struct __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;
};