std::remove_if - lambda,不从集合中删除任何内容
好吧,我想我在这里犯了一个愚蠢的错误。我有一个 DisplayDevice3d 列表,每个 DisplayDevice3d 都包含一个 DisplayMode3d 列表。我想从 DisplayDevice3d 列表中删除所有没有任何 DisplayMode3d 的项目。我正在尝试使用 Lambda 来执行此操作,即:
// If the device doesn't have any modes, remove it.
std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
[](DisplayDevice3d& device)
{
return device.Modes.size() == 0;
}
);
尽管 MyDisplayDevices 中的 6 个 DisplayMode3d 中,只有 1 个在其模式集合中具有任何 DisplayMode3d,但没有从列表中删除任何内容。
我在这里犯了什么愚蠢的错误?
编辑:
好吧,我的错误是我应该使用 MyDisplayDevices.remove_if 而不是 std::remove_if,但是下面的答案对于使用 std::remove_if :p 是正确的。
MyDisplayDevices.remove_if( [](DisplayDevice3d const & device)
{
return device.Modes.size() == 0;
});
Ok, I expect I've made a dumb mistake here. I have a list of DisplayDevice3d and each DisplayDevice3d contains a list of DisplayMode3d. I want to remove all items from the list of DisplayDevice3d that don't have any DisplayMode3d's. I'm trying to use a Lambda to do it, ie.:
// If the device doesn't have any modes, remove it.
std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
[](DisplayDevice3d& device)
{
return device.Modes.size() == 0;
}
);
Even though out of 6 DisplayMode3d's in MyDisplayDevices, only 1 has any DisplayMode3d's in its Modes collection, nothing is being removed from the list.
What numpty mistake have I made here?
Edit:
Ah ok, my mistake was I should be using MyDisplayDevices.remove_if instead of std::remove_if, however the answers below are correct for use of std::remove_if :p.
MyDisplayDevices.remove_if( [](DisplayDevice3d const & device)
{
return device.Modes.size() == 0;
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要对从remove_if返回的迭代器调用erase,它应该看起来像这样:
You need to call erase on the iterator returned from remove_if, It should look something like this:
remove_if
不会从列表中删除任何内容,只是将它们移动到末尾。您需要将其与erase
一起使用。有关更多详细信息,请参阅此问题。remove_if
doesn't remove anything from list it just moves them to end. You need to use it along witherase
. See this question for more details.remove_if
不执行调整大小,而是仅将迭代器返回到最后一个未删除元素后面的元素。该迭代器可以传递给erase()
来进行清理。remove_if
doesn't perform resizing, but instead it just returns the iterator to the element that follows the last element not removed. This iterator can be passed toerase()
to do the clean up.正如其他人提到的,有多种方法可以使其发挥作用。不过,我的建议是完全避免
remove_if
并坚持使用标准的基于迭代器的删除。下面的习惯用法适用于list
和vector
并且不会产生意外的行为。正如下面的评论提到的,当删除超过 1 个元素时,此方法的成本确实比
remove_if
更高。remove_if
的工作原理是从向量中更靠前的位置复制元素,并用紧邻其前面的向量覆盖应从向量中删除的向量。例如:remove_if 调用向量来删除所有 0 个元素:结果是:
注意向量还不正确。这是因为
remove_if
返回一个指向最后一个有效元素的迭代器...它不会自动调整向量的大小。您仍然需要在调用remove_if
返回的迭代器上调用v.erase()
。下面是一个例子
As others have mentioned, there are ways to make it work. However my advice would be to completely avoid
remove_if
and stick to a standard iterator-based removal instead. The idiom below works both forlist
andvector
and does not produce unexpected behavior.As the comments below mention, this method does have a higher cost than
remove_if
when more than 1 element is removed.remove_if
works by copying elements from further ahead in the vector, and overwriting vectors that should be removed from the vector by the one immediately in front of it. For example: remove_if called on a vector to remove all 0 elements:results in:
Notice how the vector isn't correct yet. That is because
remove_if
returns an iterator to the last valid element... it doesn't automatically resize the vector. You still need to callv.erase()
on the iterator returned from your call toremove_if
.An example is below