看了《stl源码剖析》中关于traits的部分,由于对模板还不是很熟悉,就看了一下还未完工的感觉收获很大,推荐一下。
在使用迭代器时,为了知道它的相应类型,可以使用模板的参数推导,代码如下
templatestruct MyItertypedef T value_type; T* ptr;MyIter(T* p=0) : ptr(p) { }T& operator*() const { return *ptr; }// ...};template typename I::value_type // 返回类型func(I ite){ return *ite; }// ...MyIter ite(new int(8));cout << func(ite); // 输出:8
用typename是因为I::value_type要在模板实例化的时候才能知道是不是一个类型,所以用typename声明为类型。具体可见我前面提到的那篇文章,说得很详细。
但是这样有一个问题,有些迭代器(比如指针)并不是一个类,也就用不了这个办法了。这时就要用traits思想把相应的类型萃取出来。
原始的类模板如下:
templatestruct iterator_traits { typedef typename I::value_type value_type;};
偏特化:
templatestruct iterator_traits { typedef T value_type;};
这样就得到了相应的类型,同理,对于const T*有
templatestruct iterator_traits { typedef T value_type;};
有了这个技巧,stl就可以根据需要制定提取迭代器相应类型的办法,比如对于下面五种有不同的方式提取类型
value_type
difference_typepointerpointerreferencereferenceiteratoriterator_category具体方式书中有说,就不赘述了。