std:: unique
|
定义于头文件
<algorithm>
|
||
|
template
<
class
ForwardIt
>
ForwardIt unique ( ForwardIt first, ForwardIt last ) ; |
(1) | (C++20 起为 constexpr) |
|
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) | (C++20 起为 constexpr) |
|
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 起) |
目录 |
说明
移除操作通过移动范围内的元素来实现,使得不需要被移除的元素出现在范围的起始位置。
- 移位操作通过 复制赋值 (C++11 前) 移动赋值 (C++11 起) 完成。
- 移除操作是稳定的:未被移除元素的相对顺序保持不变。
-
底层序列
[first,last)的长度不会因移除操作而缩短。设返回的迭代器为 result :
-
-
所有位于
[result,last)区间内的迭代器仍然保持 可解引用 特性。
-
所有位于
|
(since C++11) |
参数
| first, last | - | 定义待处理元素范围的迭代器对 |
| policy | - | 要使用的执行策略 |
| p | - |
若元素应被视为相等则返回
true
的二元谓词
谓词函数的签名应等价于如下形式: bool pred ( const Type1 & a, const Type2 & b ) ;
虽然签名不必包含
const
&
,但函数不得修改传递给它的对象,且必须能够接受所有(可能为 const 的)
|
| 类型要求 | ||
-
ForwardIt
必须满足
向前迭代器
的要求。
|
||
-
ForwardIt
所得的类型必须满足
可移动赋值
的要求。
|
||
返回值
指向范围新末尾的
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; } |
` 和 `
` 标签内的C++代码
- 仅翻译了函数签名外的文本描述(版本号)
- 保持了原始格式和结构
注解
调用
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 | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 202 | C++98 |
若使用非等价关系比较元素
其行为不明确 |
此情况下的行为
是未定义的 |
参见
|
查找首个相邻的相等元素(或满足给定谓词的元素)
(函数模板) |
|
|
创建不包含连续重复元素的区间副本
(函数模板) |
|
|
移除满足特定条件的元素
(函数模板) |
|
|
移除连续重复元素
(
std::list<T,Allocator>
的公开成员函数)
|
|
|
移除连续重复元素
(
std::forward_list<T,Allocator>
的公开成员函数)
|
|
|
(C++20)
|
移除区间中的连续重复元素
(算法函数对象) |