std:: unique
|
Определено в заголовке
<algorithm>
|
||
|
template
<
class
ForwardIt
>
ForwardIt unique ( ForwardIt first, ForwardIt last ) ; |
(1) | (constexpr начиная с C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt
>
ForwardIt unique
(
ExecutionPolicy
&&
policy,
|
(2) | (начиная с C++17) |
|
template
<
class
ForwardIt,
class
BinaryPred
>
ForwardIt unique ( ForwardIt first, ForwardIt last, BinaryPred p ) ; |
(3) | (constexpr начиная с C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
BinaryPred
>
|
(4) | (начиная с C++17) |
Удаляет все элементы, кроме первого, из каждой последовательной группы эквивалентных элементов в диапазоне
[
first
,
last
)
и возвращает итератор, указывающий за новый конец диапазона.
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> является true . |
(до C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> является true . |
(начиная с C++20) |
Содержание |
Объяснение
Удаление осуществляется путем сдвига элементов в диапазоне таким образом, что элементы, которые не должны быть удалены, появляются в начале диапазона.
- Сдвиг выполняется с помощью copy assignment (until C++11) move assignment (since C++11) .
- Операция удаления стабильна: относительный порядок элементов, которые не должны быть удалены, остается неизменным.
-
Базовая последовательность
[first,last)не укорачивается операцией удаления. Принимая result за возвращаемый итератор:
-
-
Все итераторы в
[result,last)остаются разыменуемыми .
-
Все итераторы в
|
(начиная с C++11) |
Параметры
| first, last | - | пара итераторов, определяющих диапазон обрабатываемых элементов |
| policy | - | используемая политика выполнения |
| p | - |
бинарный предикат, который возвращает
true
если элементы следует считать равными.
Сигнатура функции-предиката должна быть эквивалентна следующей: bool pred ( const Type1 & a, const Type2 & b ) ;
Хотя сигнатура не обязана иметь
const
&
, функция не должна модифицировать передаваемые ей объекты и должна быть способна принимать все значения типа (возможно const)
|
| Требования к типам | ||
-
ForwardIt
должен удовлетворять требованиям
LegacyForwardIterator
.
|
||
-
ForwardIt
должен удовлетворять требованиям
MoveAssignable
.
|
||
Возвращаемое значение
Указатель
ForwardIt
на новый конец диапазона.
Сложность
Дано N как std:: distance ( first, last ) :
Исключения
Перегрузки с параметром шаблона с именем
ExecutionPolicy
сообщают об ошибках следующим образом:
-
Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и
ExecutionPolicyявляется одним из стандартных политик , std::terminate вызывается. Для любой другойExecutionPolicyповедение определяется реализацией. - Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.
Возможная реализация
Смотрите также реализации в libstdc++ , libc++ , и MSVC STL .
| unique (1) |
|---|
template<class ForwardIt> ForwardIt unique(ForwardIt first, ForwardIt last) { if (first == last) return last; ForwardIt result = first; while (++first != last) if (!(*result == *first) && ++result != first) *result = std::move(*first); return ++result; } |
| unique (3) |
template<class ForwardIt, class BinaryPredicate> ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p) { if (first == last) return last; ForwardIt result = first; while (++first != last) if (!p(*result, *first) && ++result != first) *result = std::move(*first); return ++result; } |
` и `` оставлен без изменений, как и требовалось. HTML-теги и атрибуты также сохранены в оригинальном виде. Переведены только текстовые элементы вне кодовых блоков.
Примечания
Вызов
unique
обычно сопровождается вызовом функции-члена
erase
контейнера для фактического удаления элементов из контейнера.
Пример
#include <algorithm> #include <iostream> #include <vector> int main() { // вектор, содержащий несколько повторяющихся элементов std::vector<int> v{1, 2, 1, 1, 3, 3, 3, 4, 5, 4}; auto print = [&](int id) { std::cout << "@" << id << ": "; for (int i : v) std::cout << i << ' '; std::cout << '\n'; }; print(1); // удалить последовательные (смежные) дубликаты auto last = std::unique(v.begin(), v.end()); // v теперь содержит {1 2 1 3 4 5 4 x x x}, где 'x' неопределено v.erase(last, v.end()); print(2); // сортировка с последующим unique, чтобы удалить все дубликаты std::sort(v.begin(), v.end()); // {1 1 2 3 4 4 5} print(3); last = std::unique(v.begin(), v.end()); // v теперь содержит {1 2 3 4 5 x x}, где 'x' неопределено v.erase(last, v.end()); print(4); }
Вывод:
@1: 1 2 1 1 3 3 3 4 5 4 @2: 1 2 1 3 4 5 4 @3: 1 1 2 3 4 4 5 @4: 1 2 3 4 5
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 202 | C++98 |
поведение было неясным, если элементы
сравниваются с использованием отношения неэквивалентности |
поведение является
неопределённым в этом случае |
Смотрите также
|
находит первые два соседних элемента, которые равны (или удовлетворяют заданному предикату)
(шаблон функции) |
|
|
создаёт копию диапазона элементов, не содержащую последовательных дубликатов
(шаблон функции) |
|
|
удаляет элементы, удовлетворяющие определённым критериям
(шаблон функции) |
|
|
удаляет последовательные дублирующиеся элементы
(публичная функция-член
std::list<T,Allocator>
)
|
|
|
удаляет последовательные дублирующиеся элементы
(публичная функция-член
std::forward_list<T,Allocator>
)
|
|
|
(C++20)
|
удаляет последовательные дублирующиеся элементы в диапазоне
(объект функции алгоритма) |