为什么是标准不提供的擦除删除习惯的方便助手? [英] Why is a convenience helper for the erase-remove-idiom not provided by the standard?

查看:165
本文介绍了为什么是标准不提供的擦除删除习惯的方便助手?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从STL中删除集合中的项目需要使用经常使用的技术,已成为惯用语: erase-remove-idiom



这个成语最常见的用法之一是删除 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原则 - 有问题的向量需要4次。



是为什么标准不提供方便助手?



  widget_collection.erase_remove(widget); 

 c $ c> std :: erase_remove(widget_collection,widget); 

这显然可以扩展到

  widget_collection.erase_remove_if(widget,pred); 

等...

方案

此问题由提案 N4009:统一容器删除,其中说:


这是一个建议添加erase_if(container,pred)



[...]



从容器中消除不需要的元素,令人惊讶的是很难,
给出了一个将坏元素与好元素区分开来的谓词。



优点是所有的容器都有类似的
接口 - 它们有许多共同的功能,它们遵循相同的
约定。当容器接口变化时,
的数据结构之间的根本区别是负责任的。即使这些差异也可以忽略,因为STL的容器迭代器算法设计。


并且注意:


正确的响应
是使用erase-remove idiom,这是非显而易见的,必须教$ b $
/www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4273rel =nofollow> N4273:均匀集装箱擦除(第2版)看起来像是已通过。它是图书馆基础V2扩展V2 的一部分。 a>。另请参阅 C ++标准库扩展(版本2)的cppreference部分。



Wandbox上可用的gcc头版本(<6.0>版本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<< \\\
;
}

此代码也适用于 webcompiler ,似乎证实了TC的建议,这也是与MSVC 2015一起发运。


Removing items from a collection in the STL requires a technique used so often that is has become an idiom: the erase-remove-idiom

One of the most common usages of this idiom is to remove an item of type T from 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());

This is obviously very verbose, and violates the DRY principle - the vector in question is required 4 times there.

So my question is why does the standard not provide a convenience helper?

Something like

widget_collection.erase_remove(widget);

or

std::erase_remove(widget_collection, widget);

This could obviously be extended to

widget_collection.erase_remove_if(widget, pred);

etc...

解决方案

This issue is covered by proposal N4009: Uniform Container Erasure which says:

This is a proposal to add erase_if(container, pred), making it easier to eliminate unwanted elements correctly and efficiently.

[...]

It's surprisingly difficult to eliminate unwanted elements from a container, given a predicate that distinguishes "bad" elements from "good" elements.

One of the STL's major strengths is that all of its containers have similar interfaces - they have many functions in common and they follow the same conventions. When container interfaces vary, fundamental differences between their data structures are responsible. Even those differences can often be ignored, thanks to the STL's container-iterator-algorithm design.

and also notes:

The correct response is to use the erase-remove idiom, which is non-obvious and must be taught instead of discovered (it's called an "idiom" for a reason).

the latest version N4273: Uniform Container Erasure (Revision 2) looks like it was adopted. It is part of Extensions for Library Fundamentals V2 . Also see the cppreference section for C++ standard libraries extensions, version 2.

The head revision(version 6.0.0) of gcc available on Wandbox has an implementation of this header (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" ;
}

This code also work on webcompiler which seems to confirm T.C.'s suggestion that this also shipped with MSVC 2015.

这篇关于为什么是标准不提供的擦除删除习惯的方便助手?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆