xiaoguozi's Blog
Pay it forword - 我并不觉的自豪,我所尝试的事情都失败了······习惯原本生活的人不容易改变,就算现状很糟,他们也很难改变,在过程中,他们还是放弃了······他们一放弃,大家就都是输家······让爱传出去,很困难,也无法预料,人们需要更细心的观察别人,要随时注意才能保护别人,因为他们未必知道自己要什么·····

用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 小果子 阅读(207) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理