用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. 第十二章 Openwrt无法识别2.0 USB 盘

    今天新的U盘不能识别,还以为是U盘本身的问题,原来是缺少 kmod-usb-storage kmod-usb-storage-extras 这两个软件包. 软件包安装后重启便可识别.

  2. jQuery 对象和 DOM 对象

    jQuery(DOM对象) 或者 $(DOM对象) 此函数的作用是将DOM对象,转换为jQuery的对象 DOM对象其实就是javascript的函数对象,可以用来操作所有HTML元素.比如: a标签 ...

  3. OpenCV学习(2) OpenCV的配置

          下面我们在VS2010中编写一个简单的OpenCV程序,来看看如何在程序中使用OpenCV. 创建一个新的Win32 控制台程序,附加选项为空工程(empty project),并添加一个 ...

  4. dedecms织梦 v5.6 两处跨站漏洞

    漏洞版本: dedecms织梦 v5.6 漏洞描述: DedeCMS内容管理系统软件采用XML名字空间风格核心模板:模板全部使用文件形式保存,对用户设计模板.网站升级转移均提供很大的便利,健壮的模板标 ...

  5. linux 的命令 -exec 的使用

    linux中的 exec命令,-exec 后面跟的是linux的 command 命令,exec命令以分号结束‘:’, 该分号前面要放 反斜杠转义 . find . -name jquery.js - ...

  6. Yii学习笔记之二(使用gii生成一个简单的样例)

    1. 数据库准备 (1) 首先我们建一数据库 yii2test 并建立一张表例如以下: DROP TABLE IF EXISTS `posts`; CREATE TABLE `posts` ( `po ...

  7. JQuery中attr属性和jQuery.data()学习笔记

    用html直接data-key来存放,key必须全部小写. <div data-mydata="123"></div> consoloe.log($(&qu ...

  8. (剑指Offer)面试题4:替换空格

    题目: 请实现一个函数,把字符串中的每个空格替换成“%20”,例如输入“We are happy”,则输出“We%20are%20happy”. 思路: 背景: 在网络编程中,如果URL参数中含有特殊 ...

  9. 网络电台-SHOUTcast

    网络电台种类 目前的网络电台网站一般是基于以下三种协议的: mms.rtsp.http 其中mms是微软公司提出的网络流媒体协议,通常采用wma格式的文件,Android现在还不支持这种协议,也不支持 ...

  10. 转换到 StoryBoard 的公布说明(Converting to Storyboards Release Notes)

    转换到 StoryBoard 的公布说明(Converting to Storyboards Release Notes) 太阳火神的漂亮人生 (http://blog.csdn.net/opengl ...