c++ - 为什么标准没有提供 erase-remove-idiom 的便利助手?

标签 c++ stl c++17 erase-remove-idiom

从 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 - 有问题的 vector 在那里需要 4 次。

所以我的问题是为什么标准不提供便利的助手?

有点像

widget_collection.erase_remove(widget);

std::erase_remove(widget_collection, widget);

这显然可以扩展到

widget_collection.erase_remove_if(widget, pred);

等...

最佳答案

提案 N4009: Uniform Container Erasure 涵盖了此问题其中说:

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.

还有注释:

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).

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

Wandbox 上可用的 gcc 的主要修订版(版本 6.0.0)具有此 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" ;
}

此代码也适用于 webcompiler这似乎证实了 T.C. 的建议,即这也与 MSVC 2015 一起提供。

关于c++ - 为什么标准没有提供 erase-remove-idiom 的便利助手?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33523546/

相关文章:

c++ - 保证 std::container::size_type 是一个 std::size_t

c++ - 推导指南和注入(inject)的类名

c++ - 如何在更改编译器/操作系统方面使 C++ 代码健壮

c++ - 为什么语句不能出现在命名空间范围内?

c++ - 检测数组类型不起作用

c++ - 在c/c++中非阻塞写入文件

c++ - 对于 STL 或 !STL,这是个问题

c++ - 如何从双端队列中提取元素?

c++ - 由于C++17支持数组的shared_ptr,这是否意味着ctor和reset中不再需要T[]的显式删除器?

android-studio - 不再支持 GCC - C++17 - Android Studio