用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){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泛型算法,在性能和代码复杂度上面都有一定得权衡,至于在实际应用中,还是需要具体问题具体分析的。

现在还是迷糊的,下面是自己在项目中看到的师傅写的一个比较实用的方法:

template<typename T> bool compare_no(const T* s1 , const T* s2)

{

return strcmp(s1->no, s2->no) == 0;

}

template<typename T> bool less_no(const T* s1 , const T* s2)

{

return strcmp(s1->no, s2->no) < 0;

}

template<typename T> bool compare_id(const T* s1 , const T* s2)

{

return s1->id == s2->id;

}

template<typename T> bool less_id(const T* s1 , const T* s2)

{

return s1->id < s2->id;

}

//排序
 std::sort(vct_device.begin(), vct_device.end(), less_id<ST_DEVICE>);
 std::sort(vct_camer.begin(), vct_camer.end(), less_no<ST_CAMERA>);

//通过编号查找ID

vector<ST_CAMERA*>::iterator it_cam;
 ST_CAMERA tmp_cam;
 strcpy(tmp_cam.no, "888888");
 it_cam = std::find_if(vct_camer.begin(),vct_camer.end(),bind2nd(ptr_fun(compare_no<ST_CAMERA>), &tmp_cam));
 if (it_cam != vct_camer.end())
      返回值channel = (*it_cam)->channel;

//通过ID查找编号

vector<ST_CAMERA*>::iterator it_cam;
 ST_CAMERA tmp_cam;
 int camid = 0;
 tmp_cam.id = 3;
 it_cam = std::find_if(vct_camer_secd.begin(), vct_camer_secd.end(), bind2nd(ptr_fun(compare_id<ST_CAMERA>), &tmp_cam));
 if (it_cam == vct_camer_secd.end())
        返回值strcpy(camera,(*it_cam)->no);

find_if查找vector内对象的成员 作为菜鸟一直不会用也不敢用的更多相关文章

  1. 根据对象属性查找对象或者数组(根据对象属性查找某数组内符合该条件的对象,数组内对象属性check为true的对象,存放到数组内) 滚动轴样式

      1.根据对象属性查找某数组内符合该条件的对象. optionComwords:[ {optionName:"名称1", optionCode: '1'}, {optionNam ...

  2. CPP-STL:用vector保存对象时保存指针的优点, 以及reserve的使用(转)

    代码1 #include <vector> #include <stdio.h> class A { public: A() { printf("A()/n" ...

  3. 转载:用vector保存对象时保存指针的优点, 以及reserve的使用

    #include <vector> #include <stdio.h> class A { public: A() { printf("A()/n"); ...

  4. 如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类

    本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-t ...

  5. python的对象的属性(即对象的成员)是动态的

    1 python的对象的成员叫attribute 2 python的类的成员是可以动态创建的 因此,在用的时候也提供了三个内建的接口来对类的成员进行操作 2.1 getattr() 2.2 hasat ...

  6. java中使用反射做一个工具类,来为指定类中的成员变量进行赋值操作,使用与多个类对象的成员变量的赋值。

    //------------------------------------------------我是代码的分割线 // 首选是一个工具类,在该工具类里面,定义了一个方法,public void s ...

  7. JS获取中文拼音首字母,并通过拼音首字母高速查找页面内的中文内容

    实现效果: 图一: 图二: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGVzdGNzX2Ru/font/5a6L5L2T/fontsize/400/f ...

  8. Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限

    一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...

  9. Python面向对象2:类与对象的成员分析及self

    # 3. 类和对象的成员分析- 类和对象都可以存储成员,成员可以归类所有,也可以归对象所有- 类存储成员时使用的是与类关联的一个对象- 独享存储成员是是存储在当前对象中- 对象访问一个成员时,如果对象 ...

随机推荐

  1. windows端口

    端口可分为3大类: 1) 公认端口(Well Known Ports):从0到1023,它们紧密绑定于一些服务.通常这些端口的通讯明确表明了某种服务的协议.例如:80端口实际上总是HTTP通讯. 2) ...

  2. Ubuntu 12.04 LTS安装Windows字体

    内容参考自别人的博客:http://www.cnblogs.com/zhj5chengfeng/p/3251009.html 1. 为了方便,先将Windows字体拷贝到~/WinFonts下. 我是 ...

  3. Java import javax.servlet 出错

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  4. [Angular] Angular Elements Intro

    Make sure install the latest Angular v6 with Angular CLI. Checkout ght Github for the code. 1. Creat ...

  5. XML❤你并不孤单

    XML不是已不成立的,它是慢慢发展起来的.由最初的GML发展到SGML再到HTML,最后有了是1998年发展起来的可扩展标记语言. 然而XML并非替换HTML的技术,两者的存在都十分重要. XML是一 ...

  6. iOS arc和非arc 适用 宏

    iOS arc和非arc 适用 宏 1:使用宏 + (void)showAlertWithMessage:(NSString *)messages { dispatch_async(dispatch_ ...

  7. vim 查找和替换命令 替换/n和\n

    一. 字符串的查找 1. vim 中用 / 和 ? 来查找字符串,两者的区别是: /string 会高亮显示光标后匹配的第一个字符串,回车后光标移到该字符串的第一个字母: ?string 会高亮显示光 ...

  8. OPENERP 构建动态视图

    来自:http://shine-it.net/index.php/topic,16142.0.html 在openerp展示界面通常是通过定义class的view(xml文件)来实现的. 有时这种方法 ...

  9. No implementation found for long com.baidu.platform.comjni.map.commonmemcache.JNICommonMemCache.Create()

    3-21 10:14:20.833 2892-2892/? E/art: No implementation found for long com.baidu.platform.comjni.map. ...

  10. 深入探讨Linux静态库与动态库的详解(转)

    2.生成动态库并使用 linux下编译时通过 -shared 参数可以生成动态库(.so)文件,如下 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静 ...