4

STL のコレクションからアイテムを削除するには、イディオムになっている非常に頻繁に使用される手法が必要です:消去-削除-イディオム

このイディオムの最も一般的な使用法の 1 つは、あるタイプのアイテムTvector<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);

また

std::erase_remove(widget_collection, widget);

これは明らかに次のように拡張できます。

widget_collection.erase_remove_if(widget, pred);

等...

4

1 に答える 1

6

この問題は、提案N4009: Uniform Container Erasureでカバーされています。

これは、erase_if(container, pred) を追加する提案であり、不要な要素を正確かつ効率的に削除しやすくします。

[...]

「悪い」要素と「良い」要素を区別する述語がある場合、コンテナから不要な要素を削除することは驚くほど困難です。

STL の主な強みの 1 つは、すべてのコンテナーが類似したインターフェイスを備えていることです。多くの共通の機能があり、同じ規則に従っています。コンテナー インターフェイスが異なる場合、それらのデータ構造の根本的な違いが原因です。STLのcontainer-iterator-algorithm設計のおかげで、これらの違いでさえしばしば無視できます。

また、次の点にも注意してください。

正しい対応は、消去削除イディオムを使用することです。これは自明ではなく、発見するのではなく教える必要があります (理由から「イディオム」と呼ばれています)。

最新バージョンN4273: Uniform Container Erasure (Revision 2)採用されたようです。これは、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" ;
}

このコードはwebcompilerでも動作し、これは MSVC 2015 にも同梱されているという TC の提案を裏付けているようです。

于 2015-11-04T14:02:05.803 に答える