std::unique_copy
在头文件 <algorithm> 中定义 |
||
template< class InputIt, class OutputIt > OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first ); |
(1) | (从 C++20 开始为 constexpr) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first, |
(2) | (从 C++17 开始) |
template< class InputIt, class OutputIt, class BinaryPred > OutputIt unique_copy( InputIt first, InputIt last, |
(3) | (从 C++20 开始为 constexpr) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPred > |
(4) | (从 C++17 开始) |
将范围 [
first,
last)
中的元素复制到另一个范围,该范围从 d_first 开始,以确保没有连续的相等元素。每个相等元素组中只复制第一个元素。
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 开始) |
如果 *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 | - | 要使用的执行策略。有关详细信息,请参阅 execution policy。 |
p | - | 二元谓词,如果元素应被视为相等,则返回 true。 谓词函数的签名应等效于以下内容 bool pred(const Type1 &a, const Type2 &b); 虽然签名不需要具有 const &,但该函数不得修改传递给它的对象,并且必须能够接受类型 (可能是 const) |
类型要求 | ||
-InputIt 必须满足 LegacyInputIterator 的要求。 | ||
-OutputIt 必须满足 LegacyOutputIterator 的要求。 | ||
-ForwardIt1, ForwardIt2 必须满足 LegacyForwardIterator 的要求。 |
[编辑] 返回值
指向最后一个写入元素之后的元素的输出迭代器。
[编辑] 复杂度
给定 N 作为 std::distance(first, last)
对于重载 (2,4),如果 ForwardIt1
的值类型既不是 CopyConstructible 也不是 CopyAssignable,则可能会产生性能成本。
[编辑] 异常
具有名为 ExecutionPolicy
的模板参数的重载报告错误如下
- 如果作为算法的一部分调用的函数的执行抛出异常,并且
ExecutionPolicy
是 标准策略 之一,则调用 std::terminate。对于任何其他ExecutionPolicy
,行为是实现定义的。 - 如果算法无法分配内存,则抛出 std::bad_alloc。
[编辑] 可能的实现
[编辑] 备注
如果 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++11) |
将元素范围复制到新的位置 (函数模板) |
(C++20) |
创建一些元素范围的副本,其中不包含连续的重复项 (niebloid) |