如何使用lambda表达式在std::find_if中查找元素

29

我正在尝试使用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(), ???);

我不确定应该放什么在???中。

我看过的所有示例都使用硬编码值来检查ID的lambda表达式。我想要的是只有当toFind的ID与向量中某个项目的ID匹配时,才返回迭代器/成功。

我看到的所有示例都没有向我展示如何传递这两个参数。

编辑

附加信息:我必须在两种不同的情况下使用它:一种是结构体的==运算符,另一种是结构体没有==运算符-我不能创建一个因为用于此场景的匹配标准并不像等价运算符那样严格。

(感谢所有回复我的人;在一种情况下我能够使用find(),并且在另一种情况下在您的帮助下能够使用find_if())

4个回答

46

试试这个:

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,而不是一个 MyStruct 的值。


1
谢谢 - 在某个情况下,我有一个提供了 == 运算符的结构体。 - Tim
@Tim:操作符也可以作为自由函数或友元函数提供。 - Kerrek SB
谢谢,是的,我知道,但这是在一个代码库中,我正在尽可能轻松地处理现有的代码。 - Tim
更重要的是 - 我想要找到id匹配的标准与我用于此对象类型的等价标准不同。 - Tim
@Tim:是的,那么lambda表达式,或者一个命名合适的函数对象类,是可行的方法。 - Kerrek SB

9

这时就要用到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()成为一个模板,并让您接受任何类型。然后在lambda体内,我们将find_if传递的内容与toFind进行比较。

@KonradRudolph MyStruct 没有 operator== - Barry
@Barry ,我在第一次修订答案中犯了一个错误,将 val == toFind 放在了 lambda 中。很有可能这就是我收到评论的原因。只是一直没有回复评论。 - NathanOliver

1
按照以下步骤操作:
std::find_if(myVector.begin(), myVector.end(), 
          [&toFind] (const auto &ele) { return ele.m_id == toFind.m_id}; );

2
我建议在捕获列表中明确地捕获 toFind - KABoissonneault

1

您可以使用以下内容:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接