可能的重复:
remove_if 相当于 std::map
我有一组字符串:
set <wstring> strings;
// ...
我希望根据谓词删除字符串,例如:
std::remove_if ( strings.begin(), strings.end(), []( const wstring &s ) -> bool { return s == L"matching"; });
当我尝试这样做时,我收到以下编译器错误:
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1840): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>'
该错误似乎表明std::string
没有按值复制构造函数(这是非法的)。使用起来有什么不好吗std::remove_if
with std::set
?我是否应该做其他事情,例如多次迭代set::find()
其次是set::erase()
?
std::remove_if
(or std::erase
) 通过重新分配范围成员的值来工作。它不明白如何std::set
组织数据,或者如何从其内部树数据结构中删除节点。事实上,如果没有set
对象本身。
标准算法被设计为具有透明的(或至少始终易于记住的)计算复杂性。有选择地从数组中删除元素的函数set
由于需要重新平衡树,这将是 O(N log N),这并不比循环调用好my_set.remove()
。所以,标准没有提供它,而这正是你需要编写的。
另一方面,一个天真的手工编码循环从vector
一对一的时间复杂度为 O(N^2),而std::remove_if
是 O(N)。因此,在这种情况下,图书馆确实提供了切实的好处。
一个典型的循环(C++03风格):
for ( set_t::iterator i = my_set.begin(); i != my_set.end(); ) {
if ( condition ) {
my_set.erase( i ++ ); // strict C++03
// i = my_set.erase( i ); // more modern, typically accepted as C++03
} else {
++ i; // do not include ++ i inside for ( )
}
}
编辑(4年后!):i ++
那里看起来很可疑。如果什么erase
使无效i
后置自增运算符可以更新之前吗?不过,这很好,因为它是一个超载的operator++
而不是内置运算符。该功能安全更新i
就地和then返回其原始值的副本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)