STL源码剖析之 traits 技术小结【2013.12.12】
欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611
代码完全VS2005 编译通过,欢迎朋友们指教 一定虚心切磋 我是上群群主
所谓的traits编程技术(即模版编程中,确定传入类型,并调用对应重载方法的技术)
其本质就是使用了一个模版类中的嵌套类型定义,然后利用此嵌套类型而生成一个临时变量,然后根据临时变量调用重载函数。
《STL 源码剖析》的迭代器一章专门有一节Traits讲述迭代器中使用的traits技术
#include <iostream> using namespace std; //欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 //木心原创 请注明转载 博客地址 http://blog.csdn.net/moooxin class OperaAdd {}; //加 类型迭代器 class OperaSub {}; //减 类型迭代器 int TestFunc(const int &a,const int & b,OperaAdd ) //重载的加法计算方法 { return a + b; } int TestFunc(const int &a,const int & b,OperaSub ) //重载的减法计算方法 { return a - b; } template<typename iteratorT,typename dataT> //iteratorT对应 上面的 OperaAdd 和 OperaSub从而确定 迭代器类型 dataT是迭代器数据类型 class IteratorAdept{ //适配迭代器 public: IteratorAdept(){} IteratorAdept(dataT i):data(i){} typedef iteratorT valueType; dataT data; dataT operator *() const { return this->data;} IteratorAdept operator +(const IteratorAdept &a ) const { return IteratorAdept(TestFunc(this->data,a.data,iteratorT()));} //这个重载的 + 不要看成 真正意义的 + 而是为了标识是重载方法而已 所以我才用的 + 你也可以指定任何操作符 }; template<typename IteratorType> int TestIteratorFunc(const IteratorType &a,const IteratorType & b,OperaAdd ) //重载的加法计算方法 { return *a + *b; } template<typename IteratorType> int TestIteratorFunc(const IteratorType &a,const IteratorType & b,OperaSub ) //重载的减法计算方法 { return *a - *b; } template<typename IteratorType> struct TFunciton{ //仿函数 实现了 只要传迭代器 不需显示传迭代器类型 就能根据迭代器对象知道 使用那种迭代器类型计算方法 int operator()(const IteratorType &pl,const IteratorType &pr) { typedef typename IteratorType::valueType valueType;//这里需要显示声明Tp::valueType 为typedef typename 为什么? //在Effect c++的typename和class的区别那一节中有说道。 return TestIteratorFunc( pl,pr,valueType());//这里就是关键实现了, 因为valueType已经呗声明为一种类型,所以 valueType() //这样就产生一个临时valueType类型的变量,根据重载机制,根据Tp的不同,而调用了不同的TestFunc //return (pl + pr).data;//这个方法就是把重载调用放到 迭代器内部 自己调用 迭代器 根据自己的不一样 调用不一样的重载方法。 } }; template<typename IteratorType> struct TFunciton2{ IteratorType operator()(const IteratorType &pl,const IteratorType &pr) { return pl + pr; } }; template<typename DataType> struct TFunciton3Add{ int operator()(const DataType &pl,const DataType &pr) { return pl + pr; } }; template<typename DataType> struct TFunciton3Sub{ int operator()(const DataType &pl,const DataType &pr) { return pl - pr; } }; enum FORS{ Fir = 0, Snd }; template<typename T> class ContainerAdd{ //加法容器 public: typedef IteratorAdept<OperaAdd,T> iterator; ContainerAdd(int a,int b):ma(a),mb(b){}; iterator & GetData(const FORS &type = Fir){ type == Fir ? m_i.data = ma : m_i.data = mb ; return m_i;} T ma,mb; iterator m_i;//迭代器 }; template<typename T> class ContainerSub{ //减法容器 public: typedef IteratorAdept<OperaSub,T> iterator; ContainerSub(int a,int b):ma(a),mb(b){}; iterator & GetData(const FORS &type = Fir){ type == Fir ? m_i.data = ma : m_i.data = mb ; return m_i;} T ma,mb; iterator m_i;//迭代器 }; template<typename IteratorType,typename TFunc> int publicFunction1(const IteratorType &pl,const IteratorType &pr,TFunc interfaceFunc) //假设公用算法 { return interfaceFunc(pl,pr);//调用传入仿函数 执行算法 } template<typename IteratorType,typename TFunc> IteratorType publicFunction2(const IteratorType &pl,const IteratorType &pr,TFunc interfaceFunc) //假设公用算法 { return interfaceFunc(pl,pr);//调用传入仿函数 执行算法 } template<typename IteratorType,typename TFunc> int publicFunction3(const IteratorType &pl,const IteratorType &pr,TFunc interfaceFunc) { return interfaceFunc(*pl,*pr); } int _tmain(int argc, _TCHAR* argv[]) { ContainerAdd<int> add(1,2); ContainerAdd<int>::iterator il = add.GetData(Fir); ContainerAdd<int>::iterator ir = add.GetData(Snd); //使用算法 int result = publicFunction1(il,ir,TFunciton<ContainerAdd<int>::iterator>());//一个加法迭代器,相当于确定某容器的迭代器类型【容器的迭代器类型是设计初确定的】 cout << "publicFunction1 加法: 1+2=" << result << endl; ContainerAdd<int>::iterator result1(publicFunction2(il,ir,TFunciton2<ContainerAdd<int>::iterator>()).data); cout << "publicFunction2 加法: 1+2=" << *result1 << endl; int result3 = publicFunction3(il,ir,TFunciton3Add<int>()); cout << "publicFunction3 加法: 1+2=" << result3 << " 标准SGI STL用法"<<endl; ContainerSub<int> sub(2,1); ContainerSub<int>::iterator ill = sub.GetData(Fir); ContainerSub<int>::iterator irr = sub.GetData(Snd); int result4 = publicFunction1(ill,irr,TFunciton<ContainerSub<int>::iterator>()); cout << "publicFunction1 减法: 2-1=" << result4 << endl; ContainerSub<int>::iterator result5(publicFunction2(ill,irr,TFunciton2<ContainerSub<int>::iterator>()).data); cout << "publicFunction2 减法: 2-1=" << *result5 << endl; int result6 = publicFunction3(ill,irr,TFunciton3Sub<int>()); cout << "publicFunction3 减法: 2-1=" << result6 << " 标准SGI STL用法"<<endl; } //欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 //木心原创 请注明转载 博客地址 http://blog.csdn.net/moooxin