2015-11-04 4 views
5

Rimozione di elementi da una raccolta nel STL richiede una tecnica usata così spesso che è diventato un modo di dire: the erase-remove-idiomPerché un assistente di convenienza per l'erase-remove-idiom non è fornito dallo standard?

Uno degli usi più comuni di questo idioma è quello di eliminare un elemento di tipo T da un vector<T>

Questo è ovviamente molto prolisso e viola lo DRY principle - il vettore in questione è richiesto 4 volte lì.

Quindi la mia domanda è: perché lo standard non fornisce un aiuto pratico?

Qualcosa di simile

widget_collection.erase_remove(widget); 

o

std::erase_remove(widget_collection, widget); 

Questo potrebbe ovviamente essere esteso a

widget_collection.erase_remove_if(widget, pred); 

ecc ...

+0

Il freddo scrive sempre il tuo. – NathanOliver

+2

Ho! :) Ho solo pensato che sarebbe stata un'aggiunta abbastanza semplice a '', quindi tutti ne potrebbero beneficiare –

+0

@SteveLorimer che ho anch'io. Sei specializzato su 'list <>'? – curiousguy

risposta

7

Questo problema è coperto dalla proposta N4009: Uniform Container Erasure, che dice:

Si tratta di una proposta di aggiungere erase_if (container, pred), rendendo più facile per eliminare corretto ed efficiente elementi indesiderati.

[...]

È sorprendentemente difficile da eliminare elementi indesiderati da un contenitore, dato un predicato che distingue gli elementi "cattivi" da elementi "buoni".

Uno dei principali punti di forza della STL è che tutti i suoi contenitori hanno interfacce simili - hanno molte funzioni in comune e seguono le stesse convenzioni . Quando le interfacce container variano, sono fondamentali le differenze fondamentali tra loro strutture dati. Persino quelle differenze possono essere spesso ignorate , grazie al design dell'algoritmo iteratore del contenitore STL.

e rileva anche:

La risposta corretta è quello di utilizzare l'idioma erase-remove, che non è evidente e deve essere insegnata invece di scoperto (si chiama un "linguaggio" per un motivo).

l'ultima versione N4273: Uniform Container Erasure (Revision 2) sembra che fosse adopted. Fa parte di Extensions for Library Fundamentals V2. Vedi anche la sezione cppreference per C++ standard libraries extensions, version 2.

Revisione testata (versione 6.0.0) di gcc accessibile Wandbox ha un'implementazione di questa intestazione (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" ; 
} 

Questo codice funziona anche su webcompiler che sembra confermare il suggerimento di TC che anche questo fornito con MSVC 2015.

+0

Grazie! Sai dove posso trovare informazioni sui programmi di rilascio per queste estensioni? Fanno parte di C++ 14? –

+2

@SteveLorimer no, non ho prestato molta attenzione alle librerie come gruppo di lavoro principale. Ma qui [STL dice probabilmente C++ 17] (https://news.ycombinator.com/item?id=9050267) per la sua proposta. –