std::unique_copy不能直接去重,因为它只移除相邻重复元素,而非全局去重;必须先排序或确保重复元素相邻,且需满足输入有效、输出可写、目标空间足够三要素,并用返回迭代器截断结果。

std::unique_copy 为什么不能直接去重?
std::unique_copy 不是“去重函数”,它只移除**相邻重复元素**,且必须在已排序或已按重复逻辑分组的序列上才有意义。如果你直接对 {1,3,2,2,4,4,4} 调用,结果仍是 {1,3,2,4,4,4}(只删掉每组连续重复中的后续项),而非 {1,3,2,4}。这点常被误读为“去重失败”,其实是用法错位。
正确调用 std::unique_copy 的三要素
必须同时满足:输入迭代器有效、输出迭代器可写、目标容器足够大(或用 back_inserter)。漏掉任一都会导致未定义行为或静默截断。
- 输入范围需支持前向遍历(如
vector、array、原生数组指针) - 输出容器不能是只读的;若用
vector,要预先resize()或用std::back_inserter - 返回值是输出迭代器末位置——必须用它来截断多余元素,否则容器里残留旧数据
示例:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::vector<int> src = {1,1,2,2,2,3,4,4};
std::vector<int> dst(src.size()); // 预分配
auto last = std::unique_copy(src.begin(), src.end(), dst.begin());
dst.erase(last, dst.end()); // 关键:截断
// dst 现在是 {1,2,3,4}
</int></int>
和 std::unique 的关键区别在哪?
std::unique 原地修改输入容器,返回新逻辑尾迭代器;std::unique_copy 不动源数据,把结果写到别处。选哪个取决于你是否允许修改原数据、是否需要保留原始顺序(比如去重但不排序)、以及内存是否允许复制。
- 源容器不可变?→ 必须用
std::unique_copy - 源是 const 容器?→ 只能用
std::unique_copy - 想省空间且允许重排?→
std::unique+erase更高效 - 自定义相等判断?两者都支持第 4 个参数,如
std::unique_copy(first, last, out, [](int a, int b){ return abs(a) == abs(b); })
常见崩溃/错误场景
最常踩的坑是输出迭代器越界或忽略返回值:
- 用
vector::begin()向空vector写入 → 写入野地址,崩溃 - 没用返回的迭代器
last截断,导致后续读取到未初始化内存 - 对
std::list用std::unique_copy时传list::begin()但没预留空间 → 写入失败,行为未定义 - 误以为它会自动 resize 目标容器 → 它不会,C++ 标准库从不替你管理容器容量
安全写法永远包含三步:预分配/插入器 + 调用 + 截断。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










