您的位置:首页 > 大数据 > 人工智能

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

2013-12-12 10:58 218 查看
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 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl C++ 源码 traits 编程