Espacios de nombres
Variantes

std::remove, std::remove_if

De cppreference.com
 
 
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
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
 
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
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)

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)

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.

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).

Complejidad

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

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

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.

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

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)

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

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.

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]