【读书笔记】迭代器概念与traits编程技法
迭代器:提供一种方法,使之能够依序巡访某个容器内所有的元素,而又无需暴露该容器的内部表达方式。
Traits编程技法
迭代器所指对象的型别,称之为该迭代器的value type。
1 template <class T> 2 struct MyIter 3 { 4 typedef T value_type //内嵌型别声明 5 T *ptr; 6 MyIter(T *p = 0) : ptr(p) { } 7 T& operator*() const {return *ptr} 8 // .... 9 }; 10 11 12 template <class I> 13 typename I::value_type //func的返回类型 14 func(I ite) 15 { 16 return *ite; 17 } 18 19 MyIter<int> ite(new int(8)); 20 cout << func(ite) << endl; //8
上述代码中func()的返回值必须加上关键字typename,因为T是一个template参数,在它被编译器具体化之前,编译器对T一无所知。关键字typename的用意在于告诉编译器这是一个型别,如此才能顺利编译通过。
但是上面的方法有一个缺陷,并不是所有的迭代器都是class type。原生指针就不是,无法为原生指针定义内嵌型别。但是STL中必须接受原生指针作为一种迭代器。所以可以用template partial specialization(偏特化)完成。
偏特化:如果一个class template拥有一个以上的template参数,我们可以针对其中某个(或数个,但不是全部)template参数进行特化工作。
MyIter改成下面的iterator_traits
1 template <class I> 2 struct iterator_traits { 3 typedef typename I::value_type value_typ; 4 };
这个所谓的traits意义是,如果I定义有自己的value type,那么通过这个traits的作用,萃取出来的value_type就是I::value_type。func可以改成下面的写法
1 template <class I> 2 typename iterator_traits<I>::value_type 3 func(I ite) 4 { 5 return *ite; 6 }
同时令iterator_traites拥有一个偏特化版本,如下:
1 tempalte <class T> 2 struct iterator_tratis<T*> { 3 typedef T value_type; 4 };
于是原生指针int*虽然不是一种class type,也可以通过tratis萃取其value type。
这就解决了class type的迭代器和原生指针value_type的问题。