Namensräume
Varianten
Aktionen

std::remove, std::remove_if

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
removeremove_if
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Definiert in Header <algorithm>
(1)
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
(constexpr seit C++20)
(bis C++26)
template< class ForwardIt, class T = typename std::iterator_traits

                                         <ForwardIt>::value_type >
constexpr ForwardIt remove( ForwardIt first, ForwardIt last,

                            const T& value );
(seit C++26)
(2)
template< class ExecutionPolicy, class ForwardIt, class T >

ForwardIt remove( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last, const T& value );
(seit C++17)
(bis C++26)
template< class ExecutionPolicy, class ForwardIt,

          class T = typename std::iterator_traits
                        <ForwardIt>::value_type >
ForwardIt remove( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last, const T& value );
(seit C++26)
template< class ForwardIt, class UnaryPred >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPred p );
(3) (constexpr seit C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >

ForwardIt remove_if( ExecutionPolicy&& policy,

                     ForwardIt first, ForwardIt last, UnaryPred p );
(4) (seit C++17)

Entfernt alle Elemente, die bestimmte Kriterien erfüllen, aus dem Bereich [firstlast) und gibt einen Iterator nach dem Ende des neuen Bereichs zurück.

1) Entfernt alle Elemente, die gleich value sind (mittels operator==).
3) Entfernt alle Elemente, für die die Prädikatfunktion p true zurückgibt.
2,4) Dasselbe wie (1,3), aber ausgeführt gemäß policy.
Diese Überladungen nehmen an der Auflösungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true.

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true.

(seit C++20)


Wenn der Werttyp von ForwardIt nicht CopyAssignable ist, ist das Verhalten undefiniert.

(bis C++11)

Wenn der Typ von *first nicht MoveAssignable ist, ist das Verhalten undefiniert.

(seit C++11)

Inhalt

[edit] Erklärung

Das Entfernen erfolgt durch Verschieben der Elemente im Bereich, so dass die Elemente, die nicht entfernt werden sollen, am Anfang des Bereichs erscheinen.

  • Das Verschieben erfolgt durch Kopierzuweisung(bis C++11)Verschiebungszuweisung(seit C++11).
  • Der Entfernungsvorgang ist stabil: Die relative Reihenfolge der nicht zu entfernenden Elemente bleibt erhalten.
  • Die zugrunde liegende Sequenz von [firstlast) wird durch den Entfernungsvorgang nicht verkürzt. Sei result der zurückgegebene Iterator
  • Jedes Element von [resultlast) hat einen gültigen, aber undefinierten Zustand, da die Verschiebezweisung Elemente eliminieren kann, indem sie von Elementen verschiebt, die ursprünglich in diesem Bereich lagen.
(seit C++11)

[edit] Parameter

first, last - das Iteratorenpaar, das den Bereich der zu verarbeitenden Elemente definiert
value - der Wert der zu entfernenden Elemente
policy - die Ausführungsrichtlinie, die verwendet werden soll
p - unäres Prädikat, das ​true zurückgibt, wenn das Element entfernt werden soll.

Der Ausdruck p(v) muss für jedes Argument v vom Typ (möglicherweise const) VT, wobei VT der Werttyp von ForwardIt ist, unabhängig von der Wertkategorie, in bool konvertierbar sein und darf v nicht modifizieren. Daher ist ein Parametertyp von VT&nicht erlaubt, ebenso wenig wie VT es sei denn, für VT ist eine Verschiebung äquivalent zu einer Kopie(seit C++11). ​

Typanforderungen
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
UnaryPredicate muss die Anforderungen eines Prädikats erfüllen.

[edit] Rückgabewert

Iterator nach dem Ende des neuen Wertebereichs (wenn dieser nicht end ist, dann zeigt er auf einen undefinierten Wert, ebenso wie Iteratoren zu allen Werten zwischen diesem Iterator und end).

[edit] Komplexität

Gegeben sei N als std::distance(first, last).

1,2) Genau N Vergleiche unter Verwendung von operator==.
3,4) Genau N Anwendungen des Prädikats p.

[edit] Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy berichten Fehler wie folgt

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[edit] Mögliche Implementierung

remove (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value)
{
    first = std::find(first, last, value);
    if (first != last)
        for (ForwardIt i = first; ++i != last;)
            if (!(*i == value))
                *first++ = std::move(*i);
    return first;
}
remove_if (3)
template<class ForwardIt, class UnaryPred>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPred p)
{
    first = std::find_if(first, last, p);
    if (first != last)
        for (ForwardIt i = first; ++i != last;)
            if (!p(*i))
                *first++ = std::move(*i);
    return first;
}

[edit] Hinweise

Ein Aufruf von remove wird typischerweise von einem Aufruf der erase-Mitgliedsfunktion eines Containers gefolgt, um die Elemente tatsächlich aus dem Container zu entfernen. Diese beiden Aufrufe zusammen bilden das sogenannte erase-remove-Idiom.

Der gleiche Effekt kann auch durch die folgenden Nicht-Member-Funktionen erzielt werden

(seit C++20)

Die ähnlich benannten Memberfunktionen von Containern Member-Funktionen list::remove, list::remove_if, forward_list::remove und forward_list::remove_if löschen die entfernten Elemente.

Diese Algorithmen können nicht mit assoziativen Containern wie std::set und std::map verwendet werden, da ihre Iteratortypen nicht auf MoveAssignable-Typen dereferenzieren (die Schlüssel in diesen Containern sind nicht modifizierbar).

Die Standardbibliothek definiert auch eine Überladung von std::remove in <cstdio>, die einen const char* nimmt und zum Löschen von Dateien verwendet wird.

Da std::remove value per Referenz entgegennimmt, kann es unerwartete Ergebnisse liefern, wenn es sich um eine Referenz auf ein Element des Bereichs [firstlast) handelt.

Feature-Test-Makro Wert Std Feature
__cpp_lib_algorithm_default_value_type 202403 (C++26) Listeninitialisierung für Algorithmen (1,2)

[edit] Beispiel

Der folgende Code entfernt alle Leerzeichen aus einem String, indem er alle Nicht-Leerzeichen nach links verschiebt und dann die überflüssigen Zeichen löscht. Dies ist ein Beispiel für das erase-remove-Idiom.

#include <algorithm>
#include <cassert>
#include <cctype>
#include <complex>
#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
 
int main()
{
    std::string str1{"Quick  Red  Dog"};
    std::cout << "1) " << std::quoted(str1) << '\n';
    const auto noSpaceEnd = std::remove(str1.begin(), str1.end(), ' ');
    std::cout << "2) " << std::quoted(str1) << '\n';
 
    // The spaces are removed from the string only logically.
    // Note, we use view, the original string is still not shrunk:
    std::cout << "3) " << std::quoted(std::string_view(str1.begin(), noSpaceEnd))
              << ", size: " << str1.size() << '\n';
 
    str1.erase(noSpaceEnd, str1.end());
    // The spaces are removed from the string physically.
    std::cout << "4) " << std::quoted(str1) << ", size: " << str1.size() << '\n';
 
    std::string str2 = "Jumped\n Over\tA\vLazy \t  Fox\r\n";
    str2.erase(std::remove_if(str2.begin(), 
                              str2.end(),
                              [](unsigned char x) { return std::isspace(x); }),
               str2.end());
    std::cout << "5) " << std::quoted(str2) << '\n';
 
    std::vector<std::complex<double>> nums{{2, 2}, {1, 3}, {4, 8}};
    #ifdef __cpp_lib_algorithm_default_value_type
        nums.erase(std::remove(nums.begin(), nums.end(), {1, 3}), nums.end());
    #else
        nums.erase(std::remove(nums.begin(), nums.end(), std::complex<double>{1, 3}),
                   nums.end());
    #endif
    assert((nums == std::vector<std::complex<double>>{{2, 2}, {4, 8}}));
}

Ausgabe

1) "Quick  Red  Dog"
2) "QuickRedDog Dog"
3) "QuickRedDog", size: 15
4) "QuickRedDog", size: 11
5) "JumpedOverALazyFox"

[edit] Defect Reports

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 283 C++98 T musste EqualityComparable sein, aber
der Werttyp von ForwardIt ist nicht immer T
erforderte, dass der Werttyp von ForwardIt
stattdessen CopyAssignable ist

[edit] Siehe auch

Kopiert einen Bereich von Elementen und lässt diejenigen aus, die bestimmte Kriterien erfüllen
(Funktionstemplate) [edit]
Entfernt aufeinanderfolgende doppelte Elemente in einem Bereich
(Funktionstemplate) [edit]
entfernt Elemente, die bestimmte Kriterien erfüllen
(Algorithmus-Funktionsobjekt)[edit]