有没有用C支持按属性分选对象++ / STL? [英] Is there support in C++/STL for sorting objects by attribute?

查看:103
本文介绍了有没有用C支持按属性分选对象++ / STL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道是否有这个在STL支持:

说我有一个这样的类:

 类Person
{
上市:
  诠释getAge()const的;
  双getIncome()const的;
  ..
  ..
};

和一个矢量:

 矢量<人*>人;

我想样的人通过他们的年龄向量:
我知道我能做到这一点通过以下方式:

 类AgeCmp
{
上市:
   布尔运算符()(const的人* P1,常量人* P2)常量
   {
     返回P1-> getAge()&下; P2-> getAge();
   }
};
排序(people.begin(),people.end(),AgeCmp());

有没有一种更简洁的方式来做到这一点?这似乎矫枉过正必须定义一个全班只是因为我想基于一个'属性'排序。事情是这样的可能?

 排序(people.begin(),people.end(),cmpfn<人,人:: getAge>());


解决方案

通用适配器来比较基于成员属性。虽然这是相当冗长第一次是可重用的。

  //普通成员低于
模板< typename的T,typename的男,typename的C>
结构member_lt_type
{
   typedef的一二:: * member_ptr;
   member_lt_type(member_ptr P,C C):PTR(P),CMP(C){}
   布尔运算符()(T&const的放大器; LHS,T&const的放大器; RHS)常量
   {
      返回CMP(左* PTR,RHS * PTR);
   }
   member_ptr PTR;
   ÇCMP;
};//提领适配器
模板< typename的T,typename的C>
结构dereferrer
{
   dereferrer(C CMP):CMP(CMP){}
   布尔运算符()(T * LHS,T * RHS)常量{
      返回CMP(* LHS,RHS *);
   }
   ÇCMP;
};//语法糖
模板< typename的T,typename的M>
member_lt_type< T,M,性病::少< M> > member_lt(M T :: * PTR){
   返回member_lt_type< T,M,性病::少< M> >(PTR,性病::少< M>());
}模板< typename的T,typename的男,typename的C>
member_lt_type< T,M,C> member_lt(M T :: * PTR,C CMP){
   返回member_lt_type< T,M,C>(PTR,CMP);
}模板< typename的T,typename的C>
dereferrer< T,C> DEREF(C CMP){
   返回dereferrer< T,C>(CMP);
}//用法:
结构测试{INT X; }
诠释主(){
   的std ::矢量<试验>伏;
   的std ::排序(v.begin(),v.end(),member_lt(安培;测试:: X));
   的std ::排序(v.begin(),v.end(),member_lt(安培;测试:: X,性病::更大< INT>()));   的std ::矢量<测试* GT; VP;
   的std ::排序(v.begin(),v.end(),DEREF<试验>(member_lt(安培;测试:: X)));
}

I wonder if there is support in STL for this:

Say I have an class like this :

class Person
{
public:
  int getAge() const;
  double getIncome() const;
  ..
  ..
};

and a vector:

vector<Person*> people;

I would like to sort the vector of people by their age: I know I can do it the following way:

class AgeCmp
{
public:
   bool operator() ( const Person* p1, const Person* p2 ) const
   {
     return p1->getAge() < p2->getAge();
   }
};
sort( people.begin(), people.end(), AgeCmp() );

Is there a less verbose way to do this? It seems overkill to have to define a whole class just because I want to sort based on an 'attribute'. Something like this maybe?

sort( people.begin(), people.end(), cmpfn<Person,Person::getAge>() );

解决方案

Generic adaptor to compare based on member attributes. While it is quite more verbose the first time it is reusable.

// Generic member less than
template <typename T, typename M, typename C>
struct member_lt_type 
{
   typedef M T::* member_ptr;
   member_lt_type( member_ptr p, C c ) : ptr(p), cmp(c) {}
   bool operator()( T const & lhs, T const & rhs ) const 
   {
      return cmp( lhs.*ptr, rhs.*ptr );
   }
   member_ptr ptr;
   C cmp;
};

// dereference adaptor
template <typename T, typename C>
struct dereferrer
{
   dereferrer( C cmp ) : cmp(cmp) {}
   bool operator()( T * lhs, T * rhs ) const {
      return cmp( *lhs, *rhs );
   }
   C cmp;
};

// syntactic sugar
template <typename T, typename M>
member_lt_type<T,M, std::less<M> > member_lt( M T::*ptr ) {
   return member_lt_type<T,M, std::less<M> >(ptr, std::less<M>() );
}

template <typename T, typename M, typename C>
member_lt_type<T,M,C> member_lt( M T::*ptr, C cmp ) {
   return member_lt_type<T,M,C>( ptr, cmp );
}

template <typename T, typename C>
dereferrer<T,C> deref( C cmp ) {
   return dereferrer<T,C>( cmp );
}

// usage:    
struct test { int x; }
int main() {
   std::vector<test> v;
   std::sort( v.begin(), v.end(), member_lt( &test::x ) );
   std::sort( v.begin(), v.end(), member_lt( &test::x, std::greater<int>() ) );

   std::vector<test*> vp;
   std::sort( v.begin(), v.end(), deref<test>( member_lt( &test::x ) ) );
}

这篇关于有没有用C支持按属性分选对象++ / STL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆