【转】用find_if查找vector内对象的成员

http://www.yichao.info/2009/05/%E7%94%A8find_if%E6%9F%A5%E6%89%BEvector%E5%86%85%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%88%90%E5%91%98.html

用binder2nd实现find_if算法中函数对像的参数传递

用stl的find方法查找一个包含简单类型的vector中的元素是很简单的,例如

vector<string> strVec;  find(strVec.begin(),strVec.end(),”aa”);

假如vector包含一个复合类型的对象呢比如

class A
{
public:
A(const std::string str,int id)
{
this->str=str;
this->id=id;
}
private:
std::string str;
int id;
};

这个时候一般的想法是写个函数遍历这个vector,然后进行比较查找。实际上在使用STL的时候,不建议使用循环遍历的查找方法,有几个理由(参加《effictive c++》46条):

  • 效率:泛型算法通常比循环高效。
  • 正确性: 写循环时比调用泛型算法更容易产生错误。
  • 可维护性: 与相应的显式循环相比,泛型算法通常使代码更干净、更直观。

实际上通过find_if泛型算法可以很优雅的达到期望的效果。template<class InputIterator, class Predicate> InputIterator find_if( InputIterator _First, InputIterator _Last, Predicate _Pred );这里的最后一个参数可是一个一元谓词,即只带一个参数且返回值限定为bool的函数对象,例如

bool compare(A& dValue)
{
if(dValue.GetStr().compare(”bb”)==0)
return true;
else
return false;
}

示例:

vector<A> a;
A b(”aa”,4);
A c(”bb”,6);
A d(”zz”,7);
a.push_back(b);
a.push_back(c);
a.push_back(d);
vector<A>::iterator t=find_if(a.begin(),a.end(),compare);

以上函数限定了比较的内容,如果我们想要灵活的自定义比较条件的话要如何做呢,有2个办法,一个是自定义类
,并重载()操作符号,例如:

class findx
{

public:
findx(const string str)
{
class D
{};
test=str;
}
string GetTest()
{
return test;
}
bool operator()(A& dValue)
{
if(dValue.GetStr().compare(test)==0)
return true;
else
return false;

}
private:
string test;
};

比较的时候只要

vector<A>::iterator t=find_if(a.begin(),a.end(),findx(”33″));

还有一种方法是使用仿函数和绑定器。仿函数就是类似上面的重载了操作符()的自定义类,或者用struct也可以。因为他定义了操作符“()”,所 以能够像函数调用一样在对象名后加上“()”,并传入对应的参数,从而执行相应的功能。这样的类型就是函数对象,从而能作为函数参数传递给 find_if。

下面再说绑定器:STL中的绑定器有类绑定器和函数绑定器两种,类绑定器有binder1st和binder2nd,而函数绑定器是bind1st 和bind2nd,他们的基本目的都是用于构造一个一元的函数对象。比如这里我们可以利用bind2nd通过绑定二元函数对象中的第二个参数的方式来实现 二元谓词向一元谓词的转换。

struct compare: binary_function<A, string,bool>
{
bool operator()( A &value, string str) const
{
if (value.GetStr()== str)
return true;
else
return false;
}
};

示例:

vector<A>::iterator t=find_if(a.begin(),a.end(),bind2nd(compare(),”33″));

无论是用vector的循环还是find_if泛型算法,在性能和代码复杂度上面都有一定得权衡,至于在实际应用中,还是需要具体问题具体分析的

原文地址:https://www.cnblogs.com/fzzl/p/1537086.html