Namespaces
Variants

std:: remove, std:: remove_if

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
remove remove_if
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
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 [ first , last ) und gibt einen Iterator zurück, der über das neue Ende des Bereichs hinauszeigt.

1) Entfernt alle Elemente, die gleich value sind (unter Verwendung von operator == ).
3) Entfernt alle Elemente, für die das Prädikat p den Wert true zurückgibt.
2,4) Gleich wie (1,3) , aber ausgeführt gemäß policy .
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, 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)

Inhaltsverzeichnis

Erklärung

Das Entfernen erfolgt durch Verschieben der Elemente im Bereich in einer Weise, dass die nicht zu entfernenden Elemente am Anfang des Bereichs erscheinen.

  • Das Verschieben erfolgt durch copy assignment (until C++11) move assignment (since C++11) .
  • Der Entfernungsvorgang ist stabil: Die relative Reihenfolge der nicht zu entfernenden Elemente bleibt gleich.
  • Die zugrundeliegende Sequenz von [ first , last ) wird durch den Entfernungsvorgang nicht verkürzt. Mit result als zurückgegebenem Iterator:
  • Jedes Element von [ result , last ) hat einen gültigen aber unspezifizierten Zustand, da Move-Zuweisung Elemente entfernen kann, indem von Elementen bewegt wird, die ursprünglich in diesem Bereich waren.
(seit C++11)

Parameter

first, last - das Paar von Iteratoren, das den Bereich der zu verarbeitenden Elemente definiert
value - der Wert der zu entfernenden Elemente
policy - die zu verwendende Ausführungsrichtlinie
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 VT & nicht zulässig , 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 von Predicate erfüllen.

Rückgabewert

Past-the-end-Iterator für den neuen Wertebereich (falls dies nicht end ist, dann zeigt es auf einen unspezifizierten Wert, und dasselbe gilt für Iteratoren zu allen Werten zwischen diesem Iterator und end ).

Komplexität

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

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

Ausnahmen

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

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allokieren kann, wird std::bad_alloc geworfen.

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;
}

Hinweise

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

Derselbe Effekt kann auch durch die folgenden Nicht-Mitgliedsfunktionen erreicht werden:

(since C++20)

Die ähnlich benannten Container- Memberfunktionen 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 veränderbar).

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

Da std::remove den value als Referenz nimmt, kann es unerwartetes Verhalten verursachen, wenn es sich um eine Referenz auf ein Element des Bereichs [ first , last ) handelt.

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

Beispiel

Der folgende Code entfernt alle Leerzeichen aus einem String, indem alle Nicht-Leerzeichen nach links verschoben und anschließend die überflüssigen Zeichen gelöscht werden. 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';
    // Die Leerzeichen werden nur logisch aus dem String entfernt.
    // Beachten Sie, dass wir eine View verwenden, der ursprüngliche String wurde noch nicht verkleinert:
    std::cout << "3) " << std::quoted(std::string_view(str1.begin(), noSpaceEnd))
              << ", size: " << str1.size() << '\n';
    str1.erase(noSpaceEnd, str1.end());
    // Die Leerzeichen wurden physisch aus dem String entfernt.
    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"

Fehlerberichte

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

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

Siehe auch

kopiert einen Bereich von Elementen unter Auslassung derjenigen, die bestimmte Kriterien erfüllen
(Funktions-Template)
entfernt aufeinanderfolgende doppelte Elemente in einem Bereich
(Funktions-Template)
entfernt Elemente, die bestimmte Kriterien erfüllen
(Algorithmus-Funktionsobjekt)