【问题标题】:How to use lambda for std::find_if如何将 lambda 用于 std::find_if
【发布时间】:2017-08-13 12:31:57
【问题描述】:

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

【问题讨论】:

    标签: c++ lambda stl


    【解决方案1】:

    试试这个:

    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 的值。

    【讨论】:

    • 谢谢 - 在一种情况下,我有一个提供 == 运算符的结构。
    • @Tim:算子也可以作为免费函数或好友函数提供。
    • 谢谢,是的,我知道,但这是在代码库中,我试图尽可能轻松地处理现有代码
    • 更重要的是 - 我想要查找 id 匹配的标准与我用于此对象类型等价的标准不同
    • @Tim:是的,那么一个 lambda,甚至是一个适当命名的仿函数类,就是要走的路。
    【解决方案2】:

    这就是 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; } );
    

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

    【讨论】:

    • @KonradRudolph MyStruct 没有operator==
    • @Barry 我在答案的第一个修订版中搞砸了,并且在 lambda 中有 val == toFind。很可能这就是我得到评论的原因。只是再也没有回过头来评论它。
    【解决方案3】:

    您可以使用以下内容:

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

    【讨论】:

      【解决方案4】:

      执行以下操作:

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

      【讨论】:

      • 我建议在捕获列表中明确捕获toFind
      猜你喜欢
      • 1970-01-01
      • 2021-03-15
      • 2016-10-01
      • 1970-01-01
      • 2013-04-28
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      相关资源
      最近更新 更多