Namespaces
Variants

std::ranges::unique_copy, std::ranges::unique_copy_result

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p.ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenamiento y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (en rangos ordenados)
Operaciones de fusión (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de particionado
Operaciones de ordenamiento
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjunto (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de llamada
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
          class Proj = std::identity,
          std::indirect_equivalence_relation<std::projected<I, Proj>>
              C = ranges::equal_to >
requires std::indirectly_copyable<I, O> && (std::forward_iterator<I> ||
             (std::input_iterator<O> && std::same_as<std::iter_value_t<I>,
                 std::iter_value_t<O>>) || std::indirectly_copyable_storable<I, O>)
constexpr unique_copy_result<I, O>
    unique_copy( I first, S last, O result, C comp = {}, Proj proj = {} );
(1) (desde C++20)
template< ranges::input_range R, std::weakly_incrementable O,
          class Proj = std::identity,
          std::indirect_equivalence_relation<std::projected<ranges::iterator_t<R>,
              Proj>> C = ranges::equal_to >
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
             (std::forward_iterator<ranges::iterator_t<R>> ||
             (std::input_iterator<O> && std::same_as<ranges::range_value_t<R>,
                 std::iter_value_t<O>>) ||
             std::indirectly_copyable_storable<ranges::iterator_t<R>, O>)
constexpr unique_copy_result<ranges::borrowed_iterator_t<R>, O>
    unique_copy( R&& r, O result, C comp = {}, Proj proj = {} );
(2) (desde C++20)
Tipos auxiliares
template< class I, class O >
using unique_copy_result = ranges::in_out_result<I, O>;
(3) (desde C++20)
1) Copia los elementos desde el rango de origen [firstlast), al rango de destino comenzando en result de manera que no haya elementos consecutivos iguales. Solo se copia el primer elemento de cada grupo de elementos iguales.
Los rangos [firstlast) y [resultresult + N) no deben solaparse. N = ranges::distance(first, last).
Dos elementos consecutivos *(i - 1) y *i se consideran equivalentes si std::invoke(comp, std::invoke(proj, *(i - 1)), std::invoke(proj, *i)) == true, donde i es un iterador en el rango [first + 1last).
2) Igual que (1), pero usa r como rango, como si se usara ranges::begin(r) como first, y ranges::end(r) como last.

Las entidades similares a funciones descritas en esta página son objetos función de algoritmo (conocidos informalmente como niebloids), esto es:

Parámetros

first, last - el par iterador-centinela que define el rango fuente de elementos a procesar
r - el rango fuente de elementos
result - el rango destino de elementos
comp - el predicado binario para comparar los elementos proyectados
proj - la proyección a aplicar a los elementos

Valor de retorno

{ último, resultado + N }

Complejidad

Exactamente N - 1 aplicaciones del predicado correspondiente comp y no más del doble de aplicaciones de cualquier proyección proj .

Implementación posible

Consulte también las implementaciones en libstdc++ y MSVC STL (y bibliotecas de terceros: cmcstl2 , NanoRange , y range-v3 ).

struct unique_copy_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_equivalence_relation<std::projected<I,
                 Proj>> C = ranges::equal_to>
    requires std::indirectly_copyable<I, O> && (std::forward_iterator<I> ||
                 (std::input_iterator<O> && std::same_as<std::iter_value_t<I>,
                     std::iter_value_t<O>>) || std::indirectly_copyable_storable<I, O>)
    constexpr ranges::unique_copy_result<I, O>
        operator()(I first, S last, O result, C comp = {}, Proj proj = {}) const
    {
        if (!(first == last))
        {
            std::iter_value_t<I> value = *first;
            *result = value;
            ++result;
            while (!(++first == last))
            {
                auto&& value2 = *first;
                if (!std::invoke(comp, std::invoke(proj, value2),
                        std::invoke(proj, value)))
                {
                    value = std::forward<decltype(value2)>(value2);
                    *result = value;
                    ++result;
                }
            }
        }
        return {std::move(first), std::move(result)};
    }
    template<ranges::input_range R, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_equivalence_relation<std::projected<ranges::iterator_t<R>,
                 Proj>> C = ranges::equal_to>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
                 (std::forward_iterator<ranges::iterator_t<R>> ||
                 (std::input_iterator<O> && std::same_as<ranges::range_value_t<R>,
                     std::iter_value_t<O>>) ||
                 std::indirectly_copyable_storable<ranges::iterator_t<R>, O>)
    constexpr ranges::unique_copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result, C comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                       std::move(comp), std::move(proj));
    }
};
inline constexpr unique_copy_fn unique_copy {};

Ejemplo

#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <list>
#include <string>
#include <type_traits>
void print(const auto& rem, const auto& v)
{
    using V = std::remove_cvref_t<decltype(v)>;
    constexpr bool sep{std::is_same_v<typename V::value_type, int>};
    std::cout << rem << std::showpos;
    for (const auto& e : v)
        std::cout << e << (sep ? " " : "");
    std::cout << '\n';
}
int main()
{
    std::string s1{"The      string    with many       spaces!"};
    print("s1: ", s1);
    std::string s2;
    std::ranges::unique_copy(
        s1.begin(), s1.end(), std::back_inserter(s2),
        [](char c1, char c2) { return c1 == ' ' && c2 == ' '; }
    );
    print("s2: ", s2);
    const auto v1 = {-1, +1, +2, -2, -3, +3, -3};
    print("v1: ", v1);
    std::list<int> v2;
    std::ranges::unique_copy(
        v1, std::back_inserter(v2),
        {}, // comparador por defecto std::ranges::equal_to
        [](int x) { return std::abs(x); } // proyección
    );
    print("v2: ", v2);
}

Salida:

s1: The      string    with many       spaces!
s2: The string with many spaces!
v1: -1 +1 +2 -2 -3 +3 -3 
v2: -1 +2 -3

Véase también

elimina elementos duplicados consecutivos en un rango
(objeto función de algoritmo)
copia un rango de elementos a una nueva ubicación
(objeto función de algoritmo)
encuentra los dos primeros elementos adyacentes que son iguales (o satisfacen un predicado dado)
(objeto función de algoritmo)
crea una copia de algún rango de elementos que no contiene duplicados consecutivos
(plantilla de función)