从STL中的集合中删除项目需要经常使用的技术,这已成为一种习语:the erase-remove-idiom
此成语最常见的用法之一是从T
vector<T>
类型的项目
std::vector<Widget> widget_collection;
Widget widget;
widget_collection.erase(
std::remove(widget_collection.begin(), widget_collection.end(), widget),
widget_collection.end());
这显然非常冗长,并且违反了DRY principle - 有问题的向量需要4次。
所以我的问题是为什么标准不提供方便助手?
像
这样的东西widget_collection.erase_remove(widget);
或
std::erase_remove(widget_collection, widget);
这显然可以扩展到
widget_collection.erase_remove_if(widget, pred);
等...
答案 0 :(得分:6)
提案N4009: Uniform Container Erasure涵盖了此问题,其中包含:
这是一个添加erase_if(container,pred)的提议 更容易正确有效地消除不需要的元素。
[...]
从容器中消除不需要的元素是非常困难的, 给出一个谓词,将“坏”元素与“好”元素区分开来。
STL的主要优势之一是其所有容器都具有相似性 接口 - 它们有许多共同的功能,它们也遵循相同的功能 约定。当容器接口变化时,基本区别 他们的数据结构是负责任的即使这些差异往往也是如此 由于STL的容器 - 迭代器 - 算法设计,忽略了它。
还注意到:
正确的回应 是使用擦除 - 删除习语,这是非显而易见的,必须教 而不是被发现(因为某种原因,它被称为“成语”)。
最新版本N4273: Uniform Container Erasure (Revision 2)看起来像adopted。它是Extensions for Library Fundamentals V2的一部分。另请参阅C++ standard libraries extensions, version 2的cppreference部分。
Wandbox上提供的gcc头版(版本6.0.0 )具有此标题的实现( see it live ):
#include <experimental/vector>
#include <iostream>
int main()
{
std::vector<int> v1 = {1,2,3,4,5,6} ;
std::experimental::erase_if( v1, [] (const int &x ) { return x < 4; } ) ;
for( const auto & v : v1 )
{
std::cout << v << ", " ;
}
std::cout << "\n" ;
}
此代码也适用于webcompiler,这似乎证实了T.C.的建议,这也是MSVC 2015附带的。