[英]std::remove_if - lambda, not removing anything from the collection
好吧,我希望我在这里犯了一个愚蠢的错误。 我有一个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个在其Modes集合中有任何DisplayMode3d,所以没有从列表中删除任何内容。
我在这里犯了什么错误?
编辑:
好吧,我的错误是我应该使用MyDisplayDevices.remove_if而不是std :: remove_if,但是下面的答案对于使用std :: remove_if:p是正确的。
MyDisplayDevices.remove_if( [](DisplayDevice3d const & device)
{
return device.Modes.size() == 0;
});
你需要在从remove_if返回的迭代器上调用erase,它应该是这样的:
auto new_end = std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
[](const DisplayDevice3d& device)
{ return device.Modes.size() == 0; });
MyDisplayDevices.erase(new_end, MyDisplayDevices.end());
remove_if
不会从列表中删除任何内容,只是将它们移动到结尾。 您需要将其与erase
一起使用。 有关详细信息,请参阅此问题 。
正如其他人所提到的,有一些方法可以使它发挥作用。 但是我的建议是完全避免remove_if
并坚持使用标准的基于迭代器的删除。 下面的成语既适用于list
也适用于vector
,不会产生意外行为。
for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
if( iter->shouldRemove )
iter = vec.erase( iter ) ; // advances iter
else
++iter ; // don't remove
如下面的评论所述,当删除多于1个元素时,此方法的成本比remove_if
高。
remove_if
通过从向量中的更前面复制元素来工作,并覆盖应该从向量前面的向量中移除的向量。 例如:remove_if在向量上调用以删除所有0个元素:
0 1 1 0 1 0
结果是:
1 1 1 0 1 0
注意矢量是如何不正确的。 这是因为remove_if
将迭代器返回到最后一个有效元素...它不会自动调整向量的大小。 您仍然需要在调用remove_if
返回的迭代器上调用v.erase()
。
一个例子如下
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void print( vector<int> &v )
{
for( int i : v )
printf( "%d ", i );
puts("");
}
int main()
{
vector<int> v = { 0, 1, 1, 0, 1, 0 };
print( v ); // 0 1 1 0 1 0
vector<int>::iterator it = remove_if( v.begin(), v.end(), [](int i){ return i == 0; } );
print( v ); // 1 1 1 0 1 0
v.erase( it, v.end() ); // actually cut out values not wanted in vector
print( v ); // 1 1 1 (correct)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.