STL源码剖析之 traits 技术小结【2013.12.12】

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


欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧! 158427611 

你可能感兴趣的:(编程,C++,源码,STL,traits)