2015-11-04 56 views
5

删除从STL集合项目需要经常用到即成为一个成语的技术:the erase-remove-idiom为什么标准没有提供擦除 - 删除语言的便利帮助?

一本成语最常见的用法是从vector<T>

删除 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

你冷冷的时候总是写自己的。 – NathanOliver

+2

我有! :)我只是认为这对''很简单,因此所有人都可以从中受益 –

+0

@SteveLorimer我也有。你专注于'list <>'吗? – curiousguy

回答

7

此问题是由提案覆盖3210它说:

这是添加erase_if(集装箱,预计值)的建议,使其 更容易正确有效地消除不需要的元素。

[...]

这是令人惊讶的困难,以消除因为区分“好”元素“坏”的元素的谓词的容器, 不需要的元素。

STL的主要优势之一是它的所有容器都有类似的接口 - 它们有许多共同的功能,它们遵循相同的约定。当容器接口有所不同时,其数据结构之间的根本区别是有责任的。由于STL的容器迭代器算法设计,即使这些差异通常也会被忽略。

,并指出:

正确的响应 是使用擦除remove惯用法,这是非显而易见的,必须教导 ,而不是发现(这就是所谓的“成语”为一个原因)。

最新版本N4273: Uniform Container Erasure (Revision 2)看起来像是adopted。它是Extensions for Library Fundamentals V2的一部分。另请参阅C++ standard libraries extensions, version 2的cppreference部分。

头版本(版本6.0。0)上Wandbox可用的gcc有这个标题的实现(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工作,这似乎证实了TC的建议,这也随MSVC 2015年

+0

谢谢!你知道我在哪里可以找到关于这些扩展的发布时间表的信息吗?它们是C++ 14的一部分吗? –

+2

@SteveLorimer不,我没有像核心工作组那样重视图书馆工作。但是这里[STL说可能是C++ 17](https://news.ycombinator.com/item?id=9050267)。 –