如何将lambda用于std :: find_if

时间:2017-03-21 17:13:27

标签: c++ lambda stl

我正在尝试使用std :: find_if来查找符合某些条件的对象。请考虑以下事项:

struct MyStruct         
{
    MyStruct(const int & id) : m_id(id) {}                      
    int m_id;
};
...         
std::vector<MyStruct> myVector; //... assume it contains things

MyStruct toFind(1);
std::vector<MyStruct>::iterator i = std::find_if(myVector.begin(), myVector.end(), ???);

我不确定在???

中放什么

我见过的所有示例都有一个lambda,它使用硬编码值来检查ID。我想要的是仅当toFind的id与向量中的一个项的id匹配时才返回迭代器/成功。

我看到的所有示例都没有告诉我如何传递这两个参数

修改

其他信息 有两种不同的场景我必须使用它 一个结构中有一个==运算符 另一个没有operator ==的结构 - 我无法创建一个,因为找到这个场景匹配的标准不像对等运算符那样严格。

(感谢所有回复的人;我能够在一个案例中使用find(),并且在你的帮助下能够将find_if()用于另一个案例)

4 个答案:

答案 0 :(得分:9)

试试这个:

std::find_if(
    myVector.begin(), myVector.end(),
    [&toFind](const MyStruct& x) { return x.m_id == toFind.m_id;});

或者,如果您为==定义了适当的MyStruct重载,则可以使用find

std::find(myVector.begin(), myVector.end(), toFind);  // requires ==

find_if版本通常最适合您进行某种异构查找,例如,如果您刚刚获得int,而不是{{1}的值}}

答案 1 :(得分:4)

这是lambda捕获发挥作用的地方。除了说明将哪种类型的参数传递给lambda之外,您还可以说明使用哪些现有变量来构造lambda。所以在这种情况下你会有像

这样的东西
std::vector<MyStruct>::iterator i = std::find_if(myVector.begin(),
    myVector.end(), 
    [&](const auto& val){ return val.m_id == toFind.m_id; } );

因此[&]表示通过引用捕获lambda体中使用的所有变量。 (const auto& val)使lambda的operator()成为模板,并允许您接受任何类型。然后在正文中我们比较从find_if传递到toFind的内容。

答案 2 :(得分:1)

您可以使用以下内容:

MyStruct toFind(1);
std::vector<MyStruct>::iterator i =
    std::find_if(myVector.begin(), myVector.end(),
                 [&](const auto& e) { return e.id == toFind.id; });

答案 3 :(得分:0)

执行以下操作:

std::find_if(myVector.begin(), myVector.end(), 
          [&toFind] (const auto &ele) { return ele.m_id == toFind.m_id}; );