用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
小果子 閱讀(226)
評論(0) 編輯 收藏 引用 所屬分類:
C++