◐ Shell
clean mode source ↗

std::ranges::remove_copy, std::ranges::remove_copy_if, std::ranges::remove_copy_result, std::ranges::remove_copy_if_result - cppreference.com

Definido en el archivo de encabezado <algorithm>

Signatura de la llamada

template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O, class T, class Proj = std::identity > requires std::indirectly_copyable<I, O> && std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, const T*> constexpr remove_copy_result<I, O> remove_copy( I first, S last, O result, const T& value, Proj proj = {} );

(1) (desde C++20)

template< ranges::input_range R, std::weakly_incrementable O, class T, class Proj = std::identity > requires std::indirectly_copyable<ranges::iterator_t<R>, O> && std::indirect_binary_predicate<ranges::equal_to, std::projected<ranges::iterator_t<R>, Proj>, const T*> constexpr remove_copy_result<ranges::borrowed_iterator_t<R>, O> remove_copy( R&& r, O result, const T& value, Proj proj = {} );

(2) (desde C++20)

template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O, class Proj = std::identity, std::indirect_unary_predicate<std::projected<I, Proj>> Pred > requires std::indirectly_copyable<I, O> constexpr remove_copy_if_result<I, O> remove_copy_if( I first, S last, O result, Pred pred, Proj proj = {} );

(3) (desde C++20)

template< ranges::input_range R, std::weakly_incrementable O, class Proj = std::identity, std::indirect_unary_predicate< std::projected<ranges::iterator_t<R>, Proj>> Pred > requires std::indirectly_copyable<ranges::iterator_t<R>, O> constexpr remove_copy_if_result<ranges::borrowed_iterator_t<R>, O> remove_copy_if( R&& r, O result, Pred pred, Proj proj = {} );

(4) (desde C++20)

Tipos auxiliares

template< class I, class O > using remove_copy_result = ranges::in_out_result<I, O>;

(5) (desde C++20)

template< class I, class O > using remove_copy_if_result = ranges::in_out_result<I, O>;

(6) (desde C++20)

Copia elementos del rango de origen [firstlast) al rango de destino que comienza en result, omitiendo los elementos que (después de ser proyectados por proj) satisfacen un criterio específico. Si los rangos de origen y destino se superponen, el comportamiento no está definido.

1) Ignora todos los elementos que son iguales a value.

3) Ignora todos los elementos para los cuales el predicado pred devuelve true.

2,4) Igual que (1,3), pero usa r como el rango de origen, como si usara ranges::begin(r) como first, y ranges::end(r) como last.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

first, last - El rango de origen de los elementos.
r - El rango de origen de los elementos.
result - El comienzo del rango de destino.
value - El valor de los elementos a no copiar.
comp - El predicado binario con el que comparar los elementos proyectados.
proj - La proyección a aplicar a los elementos.

Valor de retorno

{last, result + N}, donde N es el número de elementos copiados.

Complejidad

Exactamente ranges::distance(first, last) aplicaciones del predicado correspondiente comp y cualquier proyección proj.

Notas

El algoritmo es estable, es decir, conserva el orden relativo de los elementos copiados.

Posible implementación

remove_copy
struct remove_copy_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             class T, class Proj = std::identity>
    requires std::indirectly_copyable<I, O> &&
             std::indirect_binary_predicate<ranges::equal_to,
                                            std::projected<I, Proj>, const T*>
    constexpr ranges::remove_copy_result<I, O>
        operator()(I first, S last, O result, const T& value, Proj proj = {}) const
    {
        for (; !(first == last); ++first)
        {
            if (value != std::invoke(proj, *first))
            {
                *result = *first;
                ++result;
            }
        }
        return {std::move(first), std::move(result)};
    }

    template<ranges::input_range R, std::weakly_incrementable O, class T,
             class Proj = std::identity>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
             std::indirect_binary_predicate<ranges::equal_to,
             std::projected<ranges::iterator_t<R>, Proj>, const T*>
    constexpr ranges::remove_copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result, const T& value, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result), value,
                       std::move(proj));
    }
};

inline constexpr remove_copy_fn remove_copy {};
remove_copy_if
struct remove_copy_if_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
    requires std::indirectly_copyable<I, O>
    constexpr ranges::remove_copy_if_result<I, O>
        operator()(I first, S last, O result, Pred pred, Proj proj = {}) const
    {
        for (; first != last; ++first)
        {
            if (false == std::invoke(pred, std::invoke(proj, *first)))
            {
                *result = *first;
                ++result;
            }
        }
        return {std::move(first), std::move(result)};
    }

    template<ranges::input_range R, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate<
                 std::projected<ranges::iterator_t<R>, Proj>> Pred>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::remove_copy_if_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                       std::move(pred), std::move(proj));
    }
};

inline constexpr remove_copy_if_fn remove_copy_if {};

Ejemplo

#include <algorithm>
#include <array>
#include <complex>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string_view>
#include <vector>

void print(const auto rem, const auto& v)
{
    std::cout << rem << ' ';
    for (const auto& e : v)
        std::cout << e << ' ';
    std::cout << '\n';
}

int main()
{
    // Filtrar el símbolo hash de la cadena dada.
    const std::string_view str {"#Optimización #De #Búfer #Pequeño"};
    std::cout << "antes: " << std::quoted(str) << '\n';

    std::cout << "después:  \"";
    std::ranges::remove_copy(str.begin(), str.end(),
                             std::ostream_iterator<char>(std::cout), '#');
    std::cout << "\"\n";

    // Copiar solo los números complejos con parte imaginaria positiva.
    using Ci = std::complex<int>;
    constexpr std::array<Ci, 5> source
    {
        Ci {1, 0}, Ci {0, 1}, Ci {2, -1}, Ci {3, 2}, Ci {4, -3}
    };
    std::vector<std::complex<int>> target;

    std::ranges::remove_copy_if(
        source,
        std::back_inserter(target),
        [](int imag) { return imag <= 0; },
        [](Ci z) { return z.imag(); }
    );

    print("origen:", source);
    print("destino:", target);
}

Salida:

antes: "#Optimización #De #Búfer #Pequeño"
después:  "Optimización De Búfer Pequeño"
origen: (1,0) (0,1) (2,-1) (3,2) (4,-3)
destino: (0,1) (3,2)

Véase también

Elimina elementos que satisfacen un criterio específico.
(niebloid) [editar]
Copia un rango de elementos a una nueva ubicación.
(niebloid) [editar]
Copia un número de elementos a una nueva ubicación.
(niebloid) [editar]
Copia un rango de elementos en orden inverso.
(niebloid) [editar]
Copia un rango, reemplazando los elementos que satisfacen un criterio específico con otro valor.
(niebloid) [editar]
Crea una copia de un rango que está invertido.
(niebloid) [editar]
Copia y rota un rango de elementos.
(niebloid) [editar]
Crea una copia de algún rango de elementos que no contiene duplicados consecutivos.
(niebloid) [editar]
Copia un rango de elementos omitiendo los que satisfacen un criterio específico
(plantilla de función) [editar]