std::unique_copy
Определён в заголовочном файле <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, так, чтобы в нём не было соседних равных элементов. Копируется только первый элемент каждой группы равных элементов.
p.p не задаёт отношение эквивалентности, поведение не определено.policy.true: |
| (до C++20) |
|
| (начиная с C++20) |
Если *d_first = *first некорректно(до C++20)*first нельзя записать в d_first(начиная с C++20), программа некорректна.
Если исходный и целевой диапазоны перекрываются, поведение не определено.
Пусть T — тип значения InputIt. Если перегрузка (1) или (3) не удовлетворяет всем следующим условиям, поведение не определено:
| (до C++20) |
| (начиная с C++20) |
-
Tудовлетворяет требованиям CopyConstructible и CopyAssignable. - Выполняются все следующие условия:
-
OutputItсоответствует требованиям LegacyForwardIterator. - Тип значения
OutputItтакже являетсяT. -
Tудовлетворяет требованиям CopyAssignable.
Параметры
| first, last | - | пара итераторов, задающая исходный диапазон обрабатываемых элементов |
| d_first | - | начало целевого диапазона |
| policy | - | используемая политика выполнения |
| p | - | бинарный предикат, возвращающий true, если элементы следует считать равными. Сигнатура функции-предиката должна быть эквивалентна следующей: boolpred(constType1&a,constType2&b); Хотя сигнатура не обязана содержать |
| Требования к типам | ||
-InputIt должен соответствовать требованиям LegacyInputIterator. |
||
-OutputIt должен соответствовать требованиям LegacyOutputIterator. |
||
-ForwardIt1, ForwardIt2 должен соответствовать требованиям LegacyForwardIterator. |
||
Возвращаемое значение
Выходной итератор, указывающий на элемент после последнего записанного элемента.
Сложность
Пусть \(\scriptsize N\)N — std::distance(first, last):
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 | требование предъявляется при определённых условиях |
См. также
| находит первые два соседних элемента, которые равны (или удовлетворяют заданному предикату) (шаблон функции и функциональный объект-алгоритм) |
|
|
(C++20) | |
| удаляет соседние повторяющиеся элементы из диапазона (шаблон функции и функциональный объект-алгоритм) |
|
|
(C++20) | |
|
(C++11) | копирует диапазон элементов в новое место (шаблон функции и функциональный объект-алгоритм) |
|
(C++20)(C++20) | |
|
(C++20) | создаёт копию части диапазона элементов, в которой нет соседних дубликатов (функциональный объект-алгоритм) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/unique_copy