std :: find Object by Member [英] std::find Object by Member

查看:156
本文介绍了std :: find Object by Member的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况



我在使用STL时遇到了一个速度提升,看起来像一个正常情况,简化为:

  class Person {
string Name;
int年龄
};

矢量< Person>人;
AddPeople(people);

string s(Bob);
find(people.begin(),people.end(),s);


问题


不幸的是找到想比较整个班级。




问题


一个更好或更合适的方式做这个STL方式?建议的问题没有帮助,但我设法找到了几个相关 问题< a>但无直接解决方案。







解决方法



有一些潜在的解决方法:


  1. Forgo 查找完全(混乱,但可以重构):

      bool bBob = false ; 
    for(UINT i = 0; i< people.size(); i ++){
    if(people [i] .Name == s)
    bBob = true;
    break;
    }


  2. 提供转换运算符不能用于 find ):

      $ b string Name; 
    int年龄
    operator string(){return Name;}
    };

    人b(Bob,99);
    string s(Bob);
    b == s; //不工作
    string(b)== s; // works,but not good for find()


  3. 定义一个独立的等式运算符,有效但全局暴露):

      BOOL操作符==(Person l,string r){
    return l .Name == r;
    }


  4. 定义成员相等运算符be first):

      class Person {
    string Name;
    int年龄
    bool operator ==(string s){return Name == s;}
    };

    人b(Bob,99);
    string s(Bob);
    b == s; // works
    s == b; // does not work,but not a problem for find()



b $ b

看起来#4是最好的候选人,但没有一个是理想的或感觉STL,有些有问题。

解决方案


有没有更好或更合适的方法来做这个STL方式?


您可以使用 std :: find_if (由C ++ 11 lambdas支持):

  std :: string name =Bob 
// ...
std :: find_if(std :: begin(people),std :: end(people),
[& p.Name == name;}

注意,调用它的STL方式是C ++标准库,而不是STL(标准模板库)。STL是C ++标准库的容器和算法库的强大灵感,但两个东西不一样,参见这是关于StackOverflow的问答有关详细信息。



编辑:



由于您使用的编译器不支持lambdas,因此您可以定义自己的functor谓词:

  struct person_has_name 
{
person_has_name(std :: string const& n):name(n){}
bool operator Person const& p){return p.Name == name;}
private:
std :: string name;
};
pre>

使用 std :: find_if 这样:

  std :: string name =Bob; 
// ...
std :: find_if(people.begin(),people.end(),person_has_name(name));


Scenario

I’ve run into a speedbump while using the STL with what seems like a normal scenario, simplified here:

class Person {
  string Name;
  int    Age;
};

vector<Person> people;
AddPeople(people);

string s("Bob");
find(people.begin(), people.end(), s);


Problem

Unfortunately find wants to compare the entire class.


Question

Is there a better or more appropriate way to do this the "STL way"? The suggested questions weren’t helpful, but I managed to find a couple of related questions but no direct solution.



Work-arounds/Tests

There’s some potential work-arounds:

  1. Forgo find altogether (cluttered, but could be refactored):

    bool bBob = false;
    for (UINT i = 0; i < people.size(); i++) {
      if (people[i].Name == s)
      bBob = true;
      break;
    }
    

  2. Provide conversion operator (implicit conversion doesn’t work; explicit can’t be used in find):

    class Person {
      string Name;
      int    Age;
      operator string() {return Name;}
    };
    
    Person b ("Bob", 99);
    string s ("Bob");
           b  == s;     //doesn’t work
    string(b) == s;     //works, but no good for find()
    

  3. Define a standalone equality operator (simple, effective, but globally exposed):

    BOOL operator==(Person l, string r) {
      return l.Name == r;
    }
    

  4. Define a member equality operator (makes comparison order dependent; object must be first):

    class Person {
      string Name;
      int    Age;
      bool operator==(string s) {return Name == s;}
    };
    
    Person b ("Bob", 99);
    string s ("Bob");
    b==s;               //works
    s==b;               //doesn’t work, but not a problem for find()
    

It looks like #4 is the best candidate, but none seem ideal or feel "STL", and some have problems.

解决方案

Is there a better or more appropriate way to do this the "STL way"?

You can use std::find_if (powered by C++11 lambdas):

std::string name = "Bob";
// ...
std::find_if(std::begin(people), std::end(people), 
    [&] (Person const& p) { return p.Name == name; }

Notice, that calling it "STL way" is inappropriate. This is the C++ Standard Library, not the STL ("Standard Template Library"). The STL served as a strong inspiration for the Containers and Algorithms Library of the C++ Standard Library, but the two things are not the same. See this Q&A on StackOverflow for further information.

EDIT:

Since you are using a compiler that does not support lambdas, you can define your own functor predicate:

struct person_has_name
{
    person_has_name(std::string const& n) : name(n) { }  
    bool operator () (Person const& p) { return p.Name == name; }
private:
    std::string name;
};

And use it with std::find_if this way:

std::string name = "Bob";
// ...
std::find_if(people.begin(), people.end(), person_has_name(name));

这篇关于std :: find Object by Member的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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