C++ STL迭代器相应型别的推导总结
来源:互联网 发布:mac epub mobi 转换 编辑:程序博客网 时间:2024/09/21 08:56
在算法设计中,经常需要获取迭代器的相应型别,即迭代器所指对象的类型。C++中的RTTI typeid()可以获取型别的名称,但是无法拿它用来声明对象。
这里总结以下迭代器相应型别的获取方法。
一 利用function template的参数推导机制(argument deducation)
template <class I,class T>void func_impl(I iter,T t){ T tmp;}template <class T>inline void func(I iter){ func_impl(iter,*iter);}int main(){ int i; func(&i);}这个方法主要通过对迭代器解引用,得到迭代器所指对象,然后将迭代器和迭代器解引用后的对象,这两个参数传入func_impl函数之中,然后由编译器自动进行模板的参数推导,从而获取迭代器的相应型别。然而这种template参数推导机制方法并不适用于任何的情况,比如函数的返回值就无法利用这种方法,因为template参数推导只适合于参数,不适合于函数返回值。所以我们需要更加全面的方法。
二 声明内嵌型别
先看例子:
#include<iostream>using namespace std;template <class T>struct MyIter{typedef T value_type;T* ptr;MyIter(T* p=0):ptr(p){}T& operator*() const{return *ptr;}};template <class I>typename I::value_type func(I iter){return *iter;}int main(){MyIter<int>iter(new int(8));cout<<func(iter);//输出8 }其中func的返回值必须加上关键字typename,因为T是一个template参数,在它编译具现化之前,编译器对T一无所知,编译器此时并不知道MyIter<T>::value_type代表的是一个型别或者是一个member function或是一个data member。typename的用意是告诉编译器这是一个型别,才能通过编译。但是这种方法只适用于迭代器是一个class或者struct,因为只有class和struct才能使用内嵌型别即typedef T value_type;而对于像指针这种类型,这种方法不使用。怎么办呢,这时候模板偏特化就派上用场了。
三 模板偏特化
模板偏特化的定义:
提供另一份template的定义式,而本身仍然是一个class template,是针对任何template参数更进一步的条件限制所设计出来的一个特化版本。
template <typename T>class C{}; template <typename T>class C<T*>{};上面的第二个版本是第一个版本的偏特化,是对T这种任何型别的模板进一步的限制,只能适用于T*这种原生指针类型。
有了偏特化之后,就可以解决上面的原生指针不是class type的类型。我们可以针对“迭代器的template参数为指针”者,设计特化版本的迭代器。
#include<iostream>using namespace std;template <class T>struct MyIter{typedef T value_type;T* ptr;MyIter(T* p=0):ptr(p){}T& operator*() const{return *ptr;}};//偏特化 template <class T>struct MyIter<T*>{typedef T value_type;T* ptr;MyIter(T* p=0):ptr(p){}T& operator*() const{return *ptr;}};template <class I>typename I::value_type func(I iter){return *iter;}int main(){MyIter<int>iter1(new int(8));MyIter<int*>iter2(new int(8));//注释掉偏特化版本将出错 cout<<func(iter1)<<endl<<func(iter2); }为了方便,我们可以继续添加一个类模板,来萃取迭代器的模板类型。
template<class T>struct my_iterator_traits{typedef typename T::value_type value_type;//注意必须有typename};//对原生指针T偏特化template<class T>struct my_iterator_traits<T*>{typedef T value_type;};//对指向常对象的原生指针偏特化template<class T>struct my_iterator_traits<const T*>{typedef T value_type;};第二个和第三个版本可以萃取处原生指针的相应类型,对于const T*类型如果没有定义第三个版本,则第二个版本会把它萃取成const T。为了更好的萃取T类型,于是就定义了第三个版本。
下面是完整的程序:
#include<iostream>using namespace std;template <class T>struct MyIter{typedef T value_type;T* ptr;MyIter(T* p=0):ptr(p){}T& operator*() const{return *ptr;}};//偏特化template <class T>struct MyIter<T*>{ typedef T value_type; T* ptr; MyIter(T* p=0):ptr(p){} T& operator*() const{ return *ptr; }};template<class T>struct my_iterator_traits{typedef typename T::value_type value_type;//注意必须有typename};//对原生指针T偏特化template<class T>struct my_iterator_traits<T*>{typedef T value_type;};//对指向常对象的原生指针偏特化template<class T>struct my_iterator_traits<const T*>{typedef T value_type;};template <class I>typename my_iterator_traits<I>::value_type func(I iter){return *iter;}int main(){MyIter<int>iter1(new int(8));MyIter<int*>iter2(new int(8));cout<<func(iter1)<<endl<<func(iter2);}
若要让my_iterator_traits有效工作,必须对所有的迭代器都定义相应型别即value_type。各自都定义一个内嵌类型。不定义的就无法进入STL这个体系。
STL中常见的5中相应型别如下:
template<class T>struct my_iterator_traits{typedef typename T::iterator_category iterator_category;//迭代器分类 typedef typename T::value_type value_type;//相应型别 typedef typename T::difference_type difference_type;//两个迭代器之间的距离 typedef typename T::pointer pointer;//指针 typedef typename T::reference reference;//引用 };
0 0
- C++ STL迭代器相应型别的推导总结
- c++:参数型别的推导
- stl之迭代器相应型别
- c++STL总结
- C++STL一般总结
- stl之再看迭代器 迭代器相应型别之五 iterator_category
- 【C++】STL容器的总结
- STL浅谈(2)——链表+相应迭代器实现
- 【C++】STL常用容器总结之一:容器与迭代器
- stl之再看迭代器iterator(迭代器相应型别和iterator_traits特性以及traits特性萃取)
- STL总结:迭代器
- STL迭代器及总结
- STL迭代器总结
- Android专家级别的面试总结
- C++STL之迭代器
- C++STL 之 迭代器
- [C++] STL迭代器失效
- c++STL的迭代器
- Jmeter之正则表达式提取器
- QT moc 学习小结
- linux下apache+SVN搭建完美版
- XDL-(1)Linux文件操作命令
- ceph存储 object的attr和omap操作
- C++ STL迭代器相应型别的推导总结
- 八大排序算法
- CSS list-style 属性
- WSTMall 微信登录配置
- Qt中文手册 之 QTreeWidgetItem
- 谈论谋略
- 101. Symmetric Tree [easy] (Python)
- leetcode Gas Station
- 自己写的字符处理函数+字符处理函数