【问题标题】:Iterating over std::vector with lambda does not want to remove with remove_if用 lambda 迭代 std::vector 不想用 remove_if 删除
【发布时间】:2012-11-23 16:32:12
【问题描述】:

我在 std::vector 上使用 remove_if 时遇到了 lambda 表达式的小问题

我有以下一段代码:

    std::remove_if( openList.begin(), openList.end(), 
        [&](BoardNode& i){
            std::cout<< i.getCoordinates() << std::endl;
            std::cout<< currentNode.getCoordinates() << std::endl;
            return i.getCoordinates() == currentNode.getCoordinates(); }
        );

这并没有编译器错误,但是从上述语句中返回 true 的元素不会从向量中删除;

我被打印在屏幕上,例如

[5,5]
[5,5]

但openList 保持原样。

【问题讨论】:

  • 您确定错误来自第一个代码示例吗?
  • “在调试期间我没有得到我的坐标”是什么意思?据我所知,第一个示例是正确的,第二个示例是错误的,因为谓词采用迭代器而不是 BoardNode。
  • 另外,标题中的“不想返回正确的类型”是什么意思?您的 lambda 正确返回 bool。
  • @juanchopanza:他需要捕获currentNode。
  • 是不是元素实际上没有从向量中删除的问题?为此,您需要擦除删除习语:`openList.erase(std::remove_if(...), openList.end());

标签: c++ vector c++11 lambda remove-if


【解决方案1】:

std::remove_if 不会从向量中删除任何内容,因为它无权访问它。相反,它将您要保留的元素移动到范围的开头,使剩余的元素处于有效但未指定的状态,并返回新的结尾。

您可以使用“erase-remove”习语从向量中实际擦除它们:

openList.erase(
    std::remove_if( 
        openList.begin(), 
        openList.end(), 
        [&](BoardNode& i){return i.getCoordinates() == currentNode.getCoordinates();}),
    openList.end());

【讨论】:

  • 对不起,我真的无法理解 lambda 方括号中的内容,您能向我解释一下吗?
【解决方案2】:

我认为您打算从向量中删除项。但是你所做的,不会 真正删除向量中的项目,这会让你认为 lambda 不起作用。您需要将erase() 成员函数与std::remove 结合使用。

换句话说,你必须使用erase-remove idiom作为:

v.erase(std::remove_if(v.begin(), v.end(), your-lambda-goes-here), v.end());

【讨论】:

    【解决方案3】:

    删除是通过以这种方式移动范围内的元素来完成的 要擦除的元素被覆盖。之间的元素 范围的新旧两端具有未指定的值。一个迭代器 返回范围的新端。的相对顺序 保留下来的元素。

    http://en.cppreference.com/w/cpp/algorithm/remove

    另外,请查看该链接上的示例。

    【讨论】:

      猜你喜欢
      • 2013-06-11
      • 2011-05-27
      • 2018-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多