//最近在工作中,遇到这样一个问题: //一个类中有十几个成员数据,我需要根据不同的成员提供不同的排序方法. 如下:
class Cell { public: string name; string time; int tchDrop; double traffic; // more … };
//最近正在学习STL,所以我想结合所学的知识,设计出一种通用的方法,只要提 //供类的成员指针和排序准则(即函数对象),就可 //以同STL算法搭配,对类成员进行比较排序,比较等.
template<typename T,typename C,typename Pred=less<T> > class Comp_Mem_Data :public binary_function<C,C,bool> { public: Comp_Mem_Data( T (C::*pmd) , Pred pred=Pred() ) //Pred类采用默认构造函数,并不一定都适用。要注意。 :m_pmd(pmd),m_pred(pred) {};
//比较 两个类对象 的成员 bool operator() (const C& a , const C& b) const { return m_pred( a.*m_pmd , b.*m_pmd ); };
private: T (C::*m_pmd); //类成员指针 Pred m_pred; //比较函数 };
//仿照标准库中的 bind1st,bind2nd 的做法,提供一个方便的调用形式 template<typename T,typename C> Comp_Mem_Data<T,C,less<T> > comper_mem_data( T (C::*pmd) ) { return Comp_Mem_Data<T,C,less<T> >(pmd,less<T>() ); } template<typename T,typename C,typename Pred> Comp_Mem_Data<T,C,Pred> comper_mem_data( T (C::*pmd) ,Pred pred ) { return Comp_Mem_Data<T,C,Pred>(pmd,pred); }
//以下就可以开始比较了. // sort(vCell.begin(),vCell.end(), comper_mem_data( &Cell::name) ); //sort(vCell.begin(),vCell.end(), comper_mem_data( &Cell::traffic , greater<double>() ); //等等
//以下是测试程序 在BCB5.5 、 MSVC6.0 中测试通过
#include <stdlib.h> #include <stdio.h> #include <time.h> #include <iostream> #include <string> #include <algorithm> #include <vector> #include <functional> using namespace std;
inline ostream& operator << (ostream& out,const Cell& cell) { out<<cell.name<<" | " <<cell.time<<" | " <<cell.tchDrop<<" | " <<cell.traffic<<" | " // more … <<endl; return out; }
template<typename Container> void output(Container cont) { cout<<"cell name | time | tchDrop | traffic"<<endl; for(int j=0;j<cont.size();++j) cout<<cont[j]; }
int main() { vector<Cell> vCell; Cell cl; srand( (unsigned)time( NULL ) ); for(int i=0;i<10; ++i) { cl.name=static_cast<char>(i+'A'); cl.time=static_cast<char>(rand()%10+'1'); cl.tchDrop=rand()%100; cl.traffic=rand()*100.0/RAND_MAX; vCell.push_back(cl); }
sort(vCell.begin(),vCell.end(), comper_mem_data(&Cell::tchDrop) ); output(vCell); sort(vCell.begin(),vCell.end(), comper_mem_data(&Cell::traffic, greater<double>() ) ); output(vCell);
vector<Cell>::const_iterator iter=find_if( vCell.begin() , vCell.end() , bind2nd(comper_mem_data(&Cell::name , equal_to<string>() ),cl ) ); cout<<((iter!=vCell.end() ) ? ("cl is find") : ("cl isn't find") )<<endl;
char lc; cin>>lc; return 0; }
//程序的一个输出如下: /* cell name | time | tchDrop | traffic A | 3 | 2 | 47.0168 | C | 1 | 2 | 66.5151 | D | 5 | 19 | 86.5017 | F | 9 | 23 | 11.1087 | E | 5 | 78 | 75.7897 | G | 7 | 84 | 54.2253 | H | 7 | 88 | 61.1774 | I | 1 | 90 | 59.2578 | J | 3 | 94 | 89.9625 | B | 6 | 99 | 89.2514 | cell name | time | tchDrop | traffic J | 3 | 94 | 89.9625 | B | 6 | 99 | 89.2514 | D | 5 | 19 | 86.5017 | E | 5 | 78 | 75.7897 | C | 1 | 2 | 66.5151 | H | 7 | 88 | 61.1774 | I | 1 | 90 | 59.2578 | G | 7 | 84 | 54.2253 | A | 3 | 2 | 47.0168 | F | 9 | 23 | 11.1087 | cl is find //*/
//用同样的方法,还可以制作出比较两个类成员函数返回值的泛型类, // 类数据成员 与 同类型的常数参数相比较的泛型类来。 //此处不一一列出。
//以上不当之处,还请各位大虾不吝指教。

|