简体   繁体   English

在 object 的向量上使用 find_if

[英]Using find_if on a vector of object

I have a vector of that looks like the following:我有一个如下所示的向量:

class Foo
{
    //whatever
};

class MyClass
{
    int myInt;
    vector<Foo> foo_v;
};

And let's say, in the main :让我们说, main是:

int main (void)
{
    vector<MyClass> myClass_v;
}

I want to find a object in myClass_v that has myInt == bar .我想在myClass_v中找到一个具有myInt == bar I don't care about foo_v .我不在乎foo_v I thought of using the std::find_if function:我想过使用std::find_if function:

std::find_if(myClass_v.begin(),myClass_v.end(),condition);

with

bool MyClass::condition(MyClass mc)
{
    if(mc.myInt==5)
        return true;
    else
        return false;
}

However the compiler says that condition() is missing arguments.但是编译器说condition()缺少 arguments。 Could you tell me what am I doing wrong?你能告诉我我做错了什么吗? I thought that std::find_if would call condition(*First) , with First being a pointer to a myClass object.我认为std::find_if会调用condition(*First)First是指向myClass object 的指针。

Or is there another good way to do the same thing?还是有另一种好方法来做同样的事情?

That's not how predicates work.这不是谓词的工作方式。 You have to supply either a free function bool Comparator(const MyClass & m) {... } , or build a function object , a class that overloads operator() : You have to supply either a free function bool Comparator(const MyClass & m) {... } , or build a function object , a class that overloads operator() :

struct MyClassComp
{
  explicit MyClassComp(int i) n(i) { }
  inline bool operator()(const MyClass & m) const { return m.myInt == n; }
private:
  int n;
};

std::find_if(v.begin(), v.end(), MyClassComp(5));

In C++0x:在 C++0x 中:

std::find_if(v.begin(), v.end(),
             [](const MyClass & m) -> bool { return m.myInt == 5; });

This captureless lambda is in fact equivalent to a free function.这个无捕获的 lambda 实际上相当于一个免费的 function。 Here is a capturing version that mimics the predicate object:这是一个模仿谓词 object 的捕获版本:

const int n = find_me();
std::find_if(v.begin(), v.end(),
             [n](const MyClass & m) -> bool { return m.myInt == n; });
struct condition {
  bool operator()(const MyClass& mc) {
    return mc.myInt == 5;
  }
}

You can do it with a functor or a regular function that is not part of MyClass, or with a static function inside MyClass - here's an example with non-member function (basically just removing the MyClass:: part of the condition definition): You can do it with a functor or a regular function that is not part of MyClass, or with a static function inside MyClass - here's an example with non-member function (basically just removing the MyClass:: part of the condition definition):

#include <algorithm>
#include <vector>

using namespace std;

class Foo
{
  //whatever
};

class MyClass
{
  public:
  int myInt;
  vector<Foo> foo_v;
};

bool condition(MyClass mc)
{
  if(mc.myInt==5)
    return true;
  else
    return false;
}


int main (void)
{
  vector<MyClass> myClass_v;
  std::find_if(myClass_v.begin(),myClass_v.end(),condition);
}

Besides what Kerrek SB wrote, you can also use the member function as a predicate.除了Kerrek SB写的内容之外,您还可以使用成员 function 作为谓词。

Define it as bool MyClass::condition() { return mc.myInt==5; }将其定义为bool MyClass::condition() { return mc.myInt==5; } bool MyClass::condition() { return mc.myInt==5; } - parameter is unnecessary since it already takes object as implicit parameter. - 参数是不必要的,因为它已经将bool MyClass::condition() { return mc.myInt==5; }作为隐式参数。

When using it, wrap &MyClass::condition (pointer to a member function) in std::mem_fcn from functional header.使用它时,将&MyClass::condition (指向成员函数的指针)从功能 header 包装到std::mem_fcn中。

std::find_if(myClass_v.begin(), myClass_v.end(), std::mem_fcn(&MyClass::condition));


A more verbose way to do it, is to use std::function or std::bind .一种更详细的方法是使用std::functionstd::bind Replace:代替:

    std::mem_fcn(&MyClass::condition)

with

    std::function<bool (MyClass &)>(&MyClass::condition)    , or
    std::bind(&MyClass::condition, std::placeholders::_1).



If MyClass_v has been declared as std::vector<MyClass *> myClass_v;如果MyClass_v已被声明为std::vector<MyClass *> myClass_v; , ,

std::function<bool (MyClass &)>(&MyClass::condition) should be altered to: std::function<bool (MyClass *)>(&MyClass::condition) . std::function<bool (MyClass &)>(&MyClass::condition)应更改为: std::function<bool (MyClass *)>(&MyClass::condition) For std::mem_fn and std::bind - no changes are needed.对于std::mem_fnstd::bind - 不需要更改。


Code:代码:

#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>

class Foo{};

struct MyClass
{
    int myInt;
    std::vector<Foo> foo_v;
    bool condition(){ return myInt==5; }
};

int main (void)
{
    std::vector<MyClass> myClass_v{ {1,{}}, {3,{}}, {5,{}}, {6,{}} };
    std::cout << std::find_if(myClass_v.begin(), myClass_v.end(), std::mem_fn(&MyClass::condition))->myInt << std::endl;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM