std::partition原地分区,满足谓词的元素在前、不满足的在后,不保证内部顺序且要求双向迭代器;返回分界迭代器,时间复杂度O(n),不提供异常安全保证。

std::partition 会原地重排容器,不保证分区内部顺序
它把满足谓词的元素全挪到前半段,不满足的全挪到后半段,但不会排序——比如 std::vector{3,1,4,1,5} 按“是否为奇数”分区,结果可能是 {3,1,1,4,5} 或 {1,3,5,4,1},只要所有奇数在前、偶数在后就算正确。这点常被误当成 std::sort 的简化版,实际语义完全不同。
必须传入双向迭代器,vector/list 可用,array/string_view 不行
std::partition 要求迭代器支持 --it(即 BidirectionalIterator),所以 std::vector、std::list、std::deque 没问题;但 std::array 的迭代器虽是随机访问,标准库实现中部分场景可能触发 SFINAE 限制;更关键的是 std::string_view 迭代器只保证前向(ForwardIterator),直接传会编译失败,报错类似:no matching function for call to 'partition'。
实操建议:
- 确认容器类型支持双向迭代:优先用
std::vector或std::list - 若用
std::array,先转成std::vector再操作,或改用std::stable_partition(它对 ForwardIterator 有特化) - 别对
std::string_view直接调用——它不可修改,且迭代器不满足要求
谓词返回 true 的元素被放到前面,false 的往后挪
这个逻辑容易写反。比如想把负数放前面,谓词得写成 [](int x) { return x ,而不是 <code>x >= 0。一旦写反,结果完全颠倒,还很难一眼发现——因为分区仍“成功”,只是前后段含义对调。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见错误场景:
- 用
std::isalpha处理char时没转型,导致符号扩展:应写[](unsigned char c) { return std::isalpha(c); } - 捕获局部变量时用了
&但变量已析构,引发未定义行为——推荐值捕获或确保生命周期覆盖整个 partition 调用 - 谓词中抛异常:标准规定
std::partition不提供异常安全保证,一旦抛出,容器处于有效但未指定状态
返回值是指向“第二分区起始位置”的迭代器
它不是布尔值,也不是计数,而是个迭代器——指向第一个不满足谓词的元素。这个位置正好是两段的分界点,常用来切分后续操作:
auto it = std::partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
// [begin, it) 是偶数,[it, end) 是奇数
std::vector<int> evens(v.begin(), it);
std::vector<int> odds(it, v.end());
注意:it 可能等于 v.end()(全满足谓词)或 v.begin()(全不满足),使用前别假设它一定在中间。
性能上,std::partition 是 O(n) 时间、O(1) 额外空间,比 std::stable_partition 快,但不稳定——相同元素的相对顺序可能改变。如果需要保持原序(比如稳定分类),必须换用 std::stable_partition,代价是 O(n) 空间或 O(n log n) 时间(取决于实现)。

















