step1.首先来写一个模板函数实现获得指针指向的值
template<class T>
T Get(T* t) {
return *t;
}
int main() {
cout << Get(new int(8));
}
这里针对的是基本类型
step2.针对自定义指针(迭代器)实现
template<class T>
class Iterator {
private:
T* p;
public:
Iterator(T* np):p(np) {}
T& operator*() {
return *p;
}
};
//因为Iterator看上去并不是一个指针,所以不能用下面的形式
//template<class T>
//T Get(T* t) {
// return *t;
//}
//采用这种形式
template<class I>
? Get(I i) { //这里返回值不知道怎么写了,这就是我们现在面临的问题
return *i;
}
int main() {
Iterator<int> i(new int(2));
cout << Get(i) << endl;
}
现在的问题是如何获得迭代器所指向的类型
step3.解决:在迭代器里指出值类型
template<class T>
class Iterator {
private:
T* p;
public:
typedef T valueType; //在这里指出valueType是 T
Iterator(T* np):p(np) {}
T& operator*() {
return *p;
}
};
template<class I>
typename I::valueType Get(I i) { //返回值类型到Iterator里去找
return *i;
}
int main() {
Iterator<int> i(new int(2));
cout << Get(i) << endl;
}
目前看上去问题已经解决了
不过还有一些需要调整
目前返回值类型是通过在迭代器类里去找得到的,对于基本数据类型是不适用的
Get(new int(2)) 会出错
有两个思路,1.为Get函数增加处理基本类型的偏特化,2.添加一个中间层(traits)为我们指定返回值类型
两个思路其实核心是一样的,但是后者可以作为一个工具为其他多个方法所使用,适用性更广。
step4.traits
template<class T>
class Iterator {
private:
T* p;
public:
typedef T valueType;
Iterator(T* np):p(np) {}
T& operator*() {
return *p;
}
};
template<class I>
struct IteratorTraits {
typedef typename I::valueType valueType;
};
//偏特化
template<class T>
struct IteratorTraits<T*> {
typedef T valueType;
};
template<class I>
typename IteratorTraits<I>::valueType Get(I i) {
return *i;
}
int main() {
Iterator<int> i(new int(2));
cout << Get(i) << endl;
cout << Get(new int(8)) << endl;
}