Espacios de nombres
Variantes
Acciones

std::remove, std::remove_if

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
removeremove_if
(hasta C++17)
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Definido en el archivo de 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 satisfacen un criterio específico del rango [firstlast) y devuelve un iterador pasado el final para el nuevo final del rango.

1) Elimina todos los elementos que son iguales a value (usando operator==).
3) Elimina todos los elementos para los que el predicado p devuelve true.
2,4) Igual que (1,3), pero se ejecuta de acuerdo a la política de ejecución policy.
Estas sobrecargas no participan en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.


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

(hasta C++11)

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

(desde C++11)

Contenido

[editar] Explicación

La eliminación se realiza desplazando los elementos del rango de forma que los elementos que no se van a eliminar aparezcan al principio del rango.

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

[editar] Parámetros

first, last - El rango de elementos a procesar.
value - El valor de los elementos a eliminar.
policy - La política de ejecución a usar. Véase política de ejecución para más detalles.
p - Predicado unario que devuelve ​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 valor de ForwardIt, independientemente de la categoría de valor, y no debe modificar v. Por lo tanto, no se admite un parámetro de tipo VT&, ni es VT a menos que para VT una operación de movimiento sea equivalente a una copia (desde C++11). ​

Requisitos de tipo
-
ForwardIt debe satisfacer los requisitos de ForwardIterator.
-
UnaryPredicate debe satisfacer los requisitos de Predicado.

[editar] Valor de retorno

Iterador pasado del final para el nuevo rango de valores (si éste no es end, entonces apunta a un valor no especificado, al igual que los iteradores a cualquier valor entre este iterador y end).

[editar] Complejidad

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

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

[editar] Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reportan errores tales que:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.

[editar] Posible implementación

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

[editar] Notas

Una llamada a remove suele ir seguida de una llamada a la función miembro erase de un contenedor para eliminar elementos del contenedor. Estas dos invocaciones juntas constituyen lo que se denomina el modismo borrar-eliminar.

El mismo efecto también se puede lograr con las siguientes funciones no miembro:

  • std::erase, que tiene sobrecargas para todos los contenedores de secuencia estándar.
  • std::erase_if, que tiene sobrecargas para todos los contenedores estándar.
(desde C++20)

Las funciones miembro de nombre similar, de los contenedores list::remove, list::remove_if, forward_list::remove y forward_list::remove_if borran los elementos eliminados.

Estos algoritmos no se pueden utilizar con contenedores asociativos como std::set y std::map porque sus tipos de iterador no hacen desreferencia a los tipos AsignablePorMovimiento (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 value por referencia, puede tener un comportamiento no esperado si es una referencia a un elemento del rango [firstlast).


Macro de Prueba de característica Valor Estándar Comentario
__cpp_lib_algorithm_default_value_type 202403 (C++26) inicialización por lista para los algoritmos (1,2)

[editar] Ejemplo

El siguiente código elimina todos los espacios de una cadena desplazando todos los caracteres que no son espacios a la izquierda y luego borrando el extra. Esto es un ejemplo del modismo borrar-eliminar.

#include <algorithm>
#include <cassert>
#include <cctype>
#include <complex>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
 
int main()
{
    std::string str1 {"Texto con algunos   espacios"};
 
    auto noSpaceEnd = std::remove(str1.begin(), str1.end(), ' ');
 
    // Los espacios se eliminan de la cadena solo lógicamente.
    // Usamos una vista sobre cadena, la cadena original aún no se ha reducido:
    std::cout << std::string_view(str1.begin(), noSpaceEnd) 
              << " tamaño: " << str1.size() << '\n';
 
    str1.erase(noSpaceEnd, str1.end());
 
    // Los espacios se eliminan de la cadena físicamente.
    std::cout << str1 << " tamaño: " << str1.size() << '\n';
 
    std::string str2 = "Texto\n con\talgunos \t  espacios en blanco\n\n";
    str2.erase(std::remove_if(str2.begin(), 
                              str2.end(),
                              [](unsigned char x) { return std::isspace(x); }),
               str2.end());
    std::cout << 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:

Textoconalgunosespacios tamaño: 28
Textoconalgunosespacios tamaño: 23
Textoconalgunosespaciosenblanco

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 283 C++98 Se requería que T fuera ComparableEnIgualdad, pero
el tipo valor de ForwardIt no siempre es T.
Se requiere que el tipo valor de ForwardIt
en su lugar sea AsignablePorCopia.

[editar] Véase también

Copia un rango de elementos omitiendo los que satisfacen un criterio específico
(plantilla de función) [editar]
Elimina elementos duplicados consecutivos en un rango.
(plantilla de función) [editar]
Elimina elementos que satisfacen un criterio específico.
(niebloid) [editar]