C++ 在对象向量上使用 find_if

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6679096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:31:15  来源:igfitidea点击:

Using find_if on a vector of object

vectorc++

提问by gramm

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_vthat has myInt == bar. I don't care about foo_v. I thought of using the std::find_iffunction:

我想找到一个对象myClass_vmyInt == bar。我不在乎foo_v。我想到了使用该std::find_if功能:

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. Could you tell me what am I doing wrong? I thought that std::find_ifwould call condition(*First), with Firstbeing a pointer to a myClassobject.

但是编译器说condition()缺少参数。你能告诉我我做错了什么吗?我认为这std::find_if会调用condition(*First)First作为指向myClass对象的指针。

Or is there another good way to do the same thing?

或者有没有另一种好方法来做同样的事情?

回答by Kerrek SB

That's not how predicates work. You have to supply either a free functionbool Comparator(const MyClass & m) { ... }, or build a function object, a class that overloads operator():

这不是谓词的工作方式。你必须提供一个自由函数bool Comparator(const MyClass & m) { ... },或者构建一个函数对象,一个重载的类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. Here is a capturing version that mimics the predicate object:

这个无捕获的 lambda 实际上相当于一个自由函数。这是一个模仿谓词对象的捕获版本:

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

回答by Viktor Sehr

struct condition {
  bool operator()(const MyClass& mc) {
    return mc.myInt == 5;
  }
}

回答by naumcho

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):

您可以使用不属于 MyClass 的函子或常规函数,或使用 MyClass 中的静态函数来完成此操作 - 这是一个非成员函数示例(基本上只是删除条件定义的 MyClass:: 部分):

#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);
}

回答by MKPS

Besides what Kerrek SBwrote, you can also use the member function as a predicate.

除了Kerrek SB所写的,您还可以将成员函数用作谓词。

Define it as 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_fcnfrom functional header.

使用它时,从函数头中包装&MyClass::condition(指向成员函数的指针)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::functionor std::bind. Replace:

更详细的方法是使用std::functionor std::bind。代替:

    std::mem_fcn(&MyClass::condition)

with

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



If MyClass_vhas 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). For std::mem_fnand std::bind- no changes are needed.

std::function<bool (MyClass &)>(&MyClass::condition)应改为:std::function<bool (MyClass *)>(&MyClass::condition)。对于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;
}