用template要求写一个模板函数,返回值要求是参数类型,初步设计
template<typename T>
class AIter{
public:
AIter(T* p=0):ptr(p){};
T* ptr;
typedef T value_type;
T& operator*()const{
return *ptr;
}
T* operator->()const{
return ptr;
}
};
template<typename T>
typename T::value_type
func(T val){
return *val;
}
这方法一个缺陷就是对于不是class type的类型无能为力,比如原生指针,只有class type类型才能内嵌类型
改进--模板偏特化(template partial specialization)
声明一个类型
template<typename T>
struct stl_iterator_traits{
typedef typename T::value_type value_type;
};
原先的func可以写成这样
template<typename T>
typename stl_iterator_traits<T>::value_type
func(T val){
return *val;
}
这样还是处理不了
int* p=new int(3);
func(p);
原生指针类型,为其提供特化版本
template<typename T>
struct stl_iterator_traits<T*>{
typedef T value_type;
};
这样就能完美解决刚才问题
但是对于指向常数对象的指针
stl_iterator_traits<const int*>::value_type
我们希望暂时存储一个变量,但是我们获取的类型是const int,声明一个无法赋值的临时变量无意义,所以我们在提供一个特化版本
template<typename T>
struct stl_iterator_traits<const T*>{
typedef T value_type;
};
iterator example:
#include <iterator>
//#using <mscorlib.dll>
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
//using namespace System;
using namespace std;
template<typename T>
class ListItem{
public:
ListItem(T value){
_value=value;
_next=NULL;
}
ListItem(){
_next=NULL;
_value=0;
}
T value()const{
return _value;
}
ListItem<T>* _next;
T _value;
};
template<class Item>
class ListIter:public iterator<std::forward_iterator_tag,Item>{
public:
Item* ptr;
ListIter(Item* p=0):ptr(p){};
Item& operator*()const{
return *ptr;
}
Item* operator->()const{
return ptr;
}
ListIter& operator++(){
ptr=ptr->_next;
return *this;
}
ListIter operator++(int){
ListIter tmp=*this;
++(*this);
return tmp;
}
bool operator==(const ListIter& iter)const{
return ptr==iter.ptr;
}
bool operator!=(const ListIter& iter)const{
return ptr!=iter.ptr;
}
};
template<typename T>
bool operator==(ListItem<T>& item,T value){
return item.value()==value;
}
template<typename T>
class List{
public:
typedef ListIter<ListItem<T> > iterator;
List(){
_end=new ListItem<T>();
_front=0;
}
void insert_front(T value){
ListItem<T>* item=new ListItem<T>(value);
if(empty()){
item->_next=_end;
_front=item;
}else{
item->_next=_front;
_front=item;
}
};
bool empty(){
return _front==NULL;
}
void insert_end(T value){
//ListItem<T>* item=new ListItem<T>(value);
if(empty()){
_front=_end;
_end->_value=value;
_end->_next=new ListItem<T>();
_end=_end->_next;
}else{
_end->_value=value;
_end->_next=new ListItem<T>();
_end=_end->_next;
}
};
void display(ostream& os=cout){
ListItem<T>* head=_front;
while(head!=_end){
cout<<head->value()<<endl;
head=head->_next;
}
};
ListItem<T>* front(){
return _front;
}
private:
ListItem<T>* _end;
ListItem<T>* _front;
long _size;
};
template<typename T>
struct stl_iterator_traits{
typedef typename T::value_type value_type;
};
template<typename T>
struct stl_iterator_traits<T*>{
typedef T value_type;
};
template<typename T>
class AIter{
public:
AIter(T* p=0):ptr(p){};
T* ptr;
typedef T value_type;
T& operator*()const{
return *ptr;
}
T* operator->()const{
return ptr;
}
};
template<typename T>
typename stl_iterator_traits<T>::value_type
func(T val){
return *val;
}
int _tmain(int argc, _TCHAR* argv[])
{
List<int> list;
for(int i=0;i<5;i++){
list.insert_front(i);
list.insert_end(i+2);
}
list.display();
List<int>::iterator begin(list.front());
List<int>::iterator end;
List<int>::iterator iter;
//vector<int>::iterator itere;
AIter<int> it(new int(2));
iter=find(begin,end,2);
cout<<iter->value()<<endl;
//list.insert_end(1);
//list.insert_end(2);
//list.display();
//list.insert_end(
return 0;
}
现在对于class type 迭代器AIter,还是原生指针int* 或const int*,都能获取正确类型int
stl规定,每个迭代器都要自己内嵌型别定义的方式定义出相应型别
(待续...)
posted on 2010-10-09 13:23
小果子 阅读(217)
评论(0) 编辑 收藏 引用 所属分类:
C++