std::ranges::remove_copy, std::ranges::remove_copy_if, std::ranges::remove_copy_result, std::ranges::remove_copy_if_result
De cppreference.com
<tbody>
</tbody>
| 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 [first, last) 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:
- Las listas de argumentos de plantilla explícitas no se pueden especificar al llamar a cualquiera de ellas.
- Ninguna de ellas es visible para la búsqueda dependiente de argumentos.
- Cuando alguna de ellas se encuentra mediante la búsqueda normal no calificada como el nombre a la izquierda del operador de llamada a función, se inhibe la búsqueda dependiente de argumentos.
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
Ejecuta este código
#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
(C++20)(C++20) |
Elimina elementos que satisfacen un criterio específico. (niebloid) |
(C++20)(C++20) |
Copia un rango de elementos a una nueva ubicación. (niebloid) |
(C++20) |
Copia un número de elementos a una nueva ubicación. (niebloid) |
(C++20) |
Copia un rango de elementos en orden inverso. (niebloid) |
(C++20)(C++20) |
Copia un rango, reemplazando los elementos que satisfacen un criterio específico con otro valor. (niebloid) |
(C++20) |
Crea una copia de un rango que está invertido. (niebloid) |
(C++20) |
Copia y rota un rango de elementos. (niebloid) |
(C++20) |
Crea una copia de algún rango de elementos que no contiene duplicados consecutivos. (niebloid) |
| Copia un rango de elementos omitiendo los que satisfacen un criterio específico (plantilla de función) |