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
Definido en el encabezado <algorithm>
(1)
template < class ForwardIt, class T >
ForwardIt remove ( ForwardIt first, ForwardIt last, const T & value ) ;
(constexpr desde C++20)
(hasta C++26)
template < class ForwardIt, class T = typename std:: iterator_traits

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

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

ForwardIt remove ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, const T & value ) ;
(desde C++17)
(hasta 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 ) ;
(desde C++26)
template < class ForwardIt, class UnaryPred >
ForwardIt remove_if ( ForwardIt first, ForwardIt last, UnaryPred p ) ;
(3) (constexpr desde C++20)
template < class ExecutionPolicy, class ForwardIt, class UnaryPred >

ForwardIt remove_if ( ExecutionPolicy && policy,

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

Elimina todos los elementos que cumplen un criterio específico del rango [ first , last ) y retorna un iterador más allá del nuevo final del rango.

1) Elimina todos los elementos que son iguales a value (utilizando operator == ).
3) Elimina todos los elementos para los cuales el predicado p devuelve true .
2,4) Igual que (1,3) , pero ejecutado de acuerdo con la policy .
Estas sobrecargas participan en la resolución de sobrecarga solo si se satisfacen todas las siguientes condiciones:

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

(hasta C++20)

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

(desde C++20)


Si el tipo de valor de ForwardIt no es CopyAssignable , el comportamiento no está definido.

(hasta C++11)

Si el tipo de * first no es MoveAssignable , el comportamiento no está definido.

(desde C++11)

Contenidos

Explicación

La eliminación se realiza desplazando los elementos en el rango de tal manera que los elementos que no se deben eliminar aparezcan al principio del rango.

  • El desplazamiento se realiza mediante copy assignment (until C++11) move assignment (since C++11) .
  • La operación de eliminación es estable: el orden relativo de los elementos que no se eliminan permanece igual.
  • La secuencia subyacente de [ first , last ) no se acorta mediante la operación de eliminación. Dado result como el iterador devuelto:
  • Cada elemento de [ result , last ) tiene un estado válido pero no especificado, porque la asignación de movimiento puede eliminar elementos moviendo desde elementos que originalmente estaban en ese rango.
(desde C++11)

Parámetros

first, last - el par de iteradores que define el rango de elementos a procesar
value - el valor de los elementos a eliminar
policy - la política de ejecución a utilizar
p - predicado unario que retorna ​ true si el elemento debe ser eliminado.

La expresión p ( v ) debe ser convertible a bool para cada argumento v de tipo (posiblemente const) VT , donde VT es el tipo de valor de ForwardIt , independientemente de la categoría de valor , y no debe modificar v . Por lo tanto, no se permite un tipo de parámetro VT & , ni tampoco VT a menos que para VT un movimiento sea equivalente a una copia (since C++11) . ​

Requisitos de tipo
-
ForwardIt debe cumplir con los requisitos de LegacyForwardIterator .
-
UnaryPredicate debe cumplir con los requisitos de Predicate .

Valor de retorno

Iterador pasado por el final para el nuevo rango de valores (si este no es end , entonces apunta a un valor no especificado, y lo mismo hacen los iteradores hacia cualquier valor entre este iterador y end ).

Complejidad

Dado N como std:: distance ( first, last ) :

1,2) Exactamente N comparaciones utilizando operator == .
3,4) Exactamente N aplicaciones del predicado p .

Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy reportan errores de la siguiente manera:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y ExecutionPolicy es uno de los standard policies , std::terminate es llamado. Para cualquier otro ExecutionPolicy , el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, std::bad_alloc es lanzado.

Implementación posible

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

Notas

Una llamada a remove normalmente es seguida por una llamada a la función miembro erase del contenedor para eliminar realmente los elementos del contenedor. Estas dos invocaciones juntas constituyen el denominado erase-remove idiom .

El mismo efecto también puede lograrse mediante las siguientes funciones no miembro:

(desde C++20)

Las funciones miembro de contenedores con nombres similares member functions list::remove , list::remove_if , forward_list::remove , y forward_list::remove_if eliminan los elementos removidos.

Estos algoritmos no pueden utilizarse con contenedores asociativos como std::set y std::map porque sus tipos de iterador no se desreferencian a tipos MoveAssignable (las claves en estos contenedores no son modificables).

La biblioteca estándar también define una sobrecarga de std::remove en <cstdio> , que toma un const char * y se utiliza para eliminar archivos.

Debido a que std::remove toma el value por referencia, puede tener un comportamiento inesperado si es una referencia a un elemento del rango [ first , last ) .

Macro de prueba de características Valor Std Característica
__cpp_lib_algorithm_default_value_type 202403 (C++26) Inicialización de lista para algoritmos ( 1,2 )

Ejemplo

El siguiente código elimina todos los espacios de una cadena desplazando todos los caracteres que no son espacios hacia la izquierda y luego borrando los sobrantes. Este es un ejemplo del 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}}));
}

Salida:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 283 C++98 T se requería que fuera EqualityComparable , pero
el tipo de valor de ForwardIt no siempre es T
se requiere que el tipo de valor de ForwardIt
sea CopyAssignable en su lugar

Véase también

copia un rango de elementos omitiendo aquellos que cumplen criterios específicos
(plantilla de función)
elimina elementos duplicados consecutivos en un rango
(plantilla de función)
elimina elementos que cumplen criterios específicos
(objeto función de algoritmo)