Namespaces
Variants

std::unique_copy

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы для диапазонов (C++20)
Ограниченные алгоритмы, например, ranges::copy, ranges::sort, ...
Немодифицирующие операции с последовательностями    
Пакетные операции
(C++17)
Поисковые операции
Модифицирующие операции с последовательностями
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разбиения
(C++11)    

Операции сортировки
Операции бинарного поиска
(на разбитых диапазонах)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определён в заголовке <algorithm>
template< class InputIt, class OutputIt >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first,
                        ForwardIt1 last, ForwardIt2 d_first );
(2) (начиная с C++17)
template< class InputIt, class OutputIt, class BinaryPred >
OutputIt unique_copy( InputIt first, InputIt last,
                      OutputIt d_first, BinaryPred p );
(3) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt1,
          class ForwardIt2, class BinaryPred >
ForwardIt2 unique_copy( ExecutionPolicy&& policy,
                        ForwardIt1 first, ForwardIt1 last,
                        ForwardIt2 d_first, BinaryPred p );
(4) (начиная с C++17)

Копирует элементы из диапазона [first, last) в другой диапазон, начиная с d_first, таким образом, чтобы не было последовательных равных элементов. Копируется только первый элемент каждой группы равных элементов.

1) Элементы сравниваются с помощью operator==.
Если operator== не устанавливает отношение эквивалентности, поведение не определено.
3) Элементы сравниваются с помощью заданного бинарного предиката p.
Если p не устанавливает отношение эквивалентности, поведение не определено.
2,4) То же, что и (1,3), но выполняется в соответствии с policy.
Эти перегрузки участвуют в разрешении перегрузки только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Если *d_first = *first является недопустимым(до C++20)*first не является writable для d_first(начиная с C++20), программа является некорректной.

Если исходный и целевой диапазоны перекрываются, поведение не определено.

Если задано T как тип значения InputIt, если перегрузка (1) или (3) не удовлетворяет всем следующим условиям, поведение не определено:

(до C++20)
(начиная с C++20)
  • OutputIt удовлетворяет требованиям LegacyForwardIterator.
  • Тип значения OutputIt также является T.
  • T является CopyAssignable.

Параметры

first, last - пара итераторов, определяющих исходный диапазон элементов для обработки
d_first - начало целевого диапазона
policy - политика выполнения для использования
p - бинарный предикат, который возвращает ​ true если элементы должны рассматриваться как равные.

Сигнатура функции-предиката должна быть эквивалентна следующей:

bool pred ( const Type1 & a, const Type2 & b ) ;

Хотя сигнатура не обязана иметь const & , функция не должна изменять переданные ей объекты и должна быть способна принимать все значения типа (возможно const) Type1 и Type2 независимо от категории значения (следовательно, Type1 & не допускается , как и Type1 , если для Type1 перемещение не эквивалентно копированию (since C++11) ).
Типы Type1 и Type2 должны быть такими, чтобы объект типа InputIt мог быть разыменован и затем неявно преобразован к обоим из них. ​

Требования к типам
-
InputIt должен удовлетворять требованиям LegacyInputIterator .
-
OutputIt должен удовлетворять требованиям LegacyOutputIterator .
-
ForwardIt1, ForwardIt2 должен удовлетворять требованиям LegacyForwardIterator .

Возвращаемое значение

Выходной итератор на элемент, следующий за последним записанным элементом.

Сложность

Дано N как std:: distance ( first, last ) :

1,2) Ровно max(0,N-1) сравнений с использованием operator == .
3,4) Ровно max(0,N-1) применений предиката p .

Для перегрузок (2,4) может возникнуть снижение производительности, если тип значения ForwardIt1 не является одновременно CopyConstructible и CopyAssignable .

Исключения

Перегрузки с параметром шаблона с именем ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Возможная реализация

Смотрите также реализации в libstdc++ и libc++ .

Примечания

Если InputIt удовлетворяет требованиям LegacyForwardIterator , эта функция перечитывает входные данные для обнаружения дубликатов.

В противном случае, если OutputIt удовлетворяет требованиям LegacyForwardIterator , и тип значения InputIt совпадает с типом значения OutputIt , эта функция сравнивает * d_first с * first .

В противном случае, эта функция сравнивает * first с локальной копией элемента.

Пример

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main()
{
    std::string s1 {"A string with mmmany letters!"};
    std::cout << "Before: " << s1 << '\n';
    std::string s2;
    std::unique_copy(s1.begin(), s1.end(), std::back_inserter(s2),
                     [](char c1, char c2) { return c1 == 'm' && 'm' == c2; });
    std::cout << "After:  " << s2 << '\n';
}

Вывод:

Before: A string with mmmany letters!
After:  A string with many letters!

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 239 C++98 предикат применялся std:: distance ( first, last ) раз применяется на один раз меньше
(для непустых диапазонов)
LWG 241 C++98 тип значения InputIt не требовал быть CopyConstructible условно требуется
LWG 538 C++98 тип значения InputIt не требовал быть CopyAssignable условно требуется
LWG 2439 C++98 тип значения InputIt не требовал быть
CopyConstructible если OutputIt является LegacyForwardIterator
условно требуется

См. также

находит первые два соседних элемента, которые равны (или удовлетворяют заданному предикату)
(шаблон функции & функциональный объект алгоритма)
удаляет последовательные дублирующиеся элементы в диапазоне
(шаблон функции & функциональный объект алгоритма)
копирует диапазон элементов в новое местоположение
(шаблон функции & функциональный объект алгоритма)
создает копию некоторого диапазона элементов, не содержащую последовательных дубликатов
(функциональный объект алгоритма)