Ste*_*mer 4 c++ stl erase-remove-idiom c++17
从STL中的集合中删除项目需要使用经常使用的技术,这已成为一种成语:擦除 - 删除 - 成语
这个成语最常见的用法之一是T从a中删除一个类型的项目vector<T>
std::vector<Widget> widget_collection;
Widget widget;
widget_collection.erase(
std::remove(widget_collection.begin(), widget_collection.end(), widget),
widget_collection.end());
Run Code Online (Sandbox Code Playgroud)
这显然非常冗长,违反了DRY原则 - 有问题的载体需要4次.
所以我的问题是为什么标准不提供方便助手?
就像是
widget_collection.erase_remove(widget);
Run Code Online (Sandbox Code Playgroud)
要么
std::erase_remove(widget_collection, widget);
Run Code Online (Sandbox Code Playgroud)
这显然可以扩展到
widget_collection.erase_remove_if(widget, pred);
Run Code Online (Sandbox Code Playgroud)
等等...
这是一个添加erase_if(容器,pred)的提议,可以更容易地正确有效地消除不需要的元素.
[...]
考虑到将"坏"元素与"好"元素区分开来的谓词,从容器中消除不需要的元素是非常困难的.
STL的主要优势之一是它的所有容器都有类似的接口 - 它们有许多共同的功能,它们遵循相同的约定.当容器接口变化时,它们的数据结构之间的根本区别是负责的.由于STL的容器 - 迭代器 - 算法设计,即使这些差异也经常被忽略.
并且还注意到:
正确的反应是使用擦除 - 移除习语,这是非显而易见的,必须教导而不是被发现(因为某种原因,它被称为"习语").
最新版本N4273:Uniform Container Erasure(修订版2)看起来像是被采用了.它是Extensions for Library Fundamentals V2的一部分.另请参阅C++标准库扩展的版本2的cppreference部分.
Wandbox上可用的gcc 的头版本(版本6.0.0)具有此标头的实现(请参见实时):
#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" ;
}
Run Code Online (Sandbox Code Playgroud)
此代码也适用于webcompiler,这似乎证实了TC的建议,即MSVC 2015也附带了这个.