std::includes要求两范围均升序排列且用相同比较函数,参数顺序为全集在前子集在后,空子集返回true,适用于已排序的稳定数据,不适用未排序容器或临时数据。

std::includes 用错容器会直接编译失败
它只接受已排序的范围,不是所有“集合”都能用。比如 std::unordered_set 或未排序的 std::vector 传进去,编译器会报错或行为未定义——因为 std::includes 内部依赖有序迭代器做归并扫描,根本没做排序检查。
- 必须确保两个输入范围都升序排列(默认比较),否则结果不可靠
-
std::set和std::multiset天然有序,可直接用;std::vector要先调std::sort - 如果用自定义比较(比如降序),两个范围必须用**完全相同**的比较函数对象,否则逻辑错乱
判断 A 是否包含 B:参数顺序不能颠倒
std::includes 第一个范围是“全集”,第二个是“子集”。写成 std::includes(B.begin(), B.end(), A.begin(), A.end()) 就反了,永远返回 false(除非 B 为空)。
- 正确写法:
std::includes(A.begin(), A.end(), B.begin(), B.end()) - 空容器是合法子集:B 为空时返回 true,符合数学定义
- 如果 A 和 B 都是
std::vector,注意传迭代器范围,别传错.size()或漏掉.end()
性能比手写循环还快?不一定
它底层是单趟双指针扫描,时间复杂度 O(n+m),比暴力嵌套循环 O(n×m) 好得多。但前提是数据已经排好序;如果每次调用前都要 std::sort,那总开销很可能更差。
- 适合场景:A、B 长期稳定且已排序,比如配置项白名单、预处理索引表
- 不适合场景:临时拼出来的 vector,每次调用前都 sort —— 直接改用
std::unordered_set查找更省事 - 注意:没有针对小数据优化,元素少于 10 个时,简单遍历可能更快(CPU 分支预测友好)
常见错误:忽略相等元素的语义
std::includes 判断的是“每个 B 中的元素,在 A 中至少有同样多的副本”。比如 A = {1,2,2,3},B = {2,2} → true;但 B = {2,2,2} → false。很多人误以为只要值存在就行,其实它按多重集语义匹配。
立即学习“C++免费学习笔记(深入)”;
- 如果业务只需要“值存在”,不用管重复次数,那就别用
std::includes,改用std::all_of+std::find - 如果用
std::multiset,它自动维护排序和重复计数,配合std::includes最自然 - 自定义比较时,要确保 “等价” 定义一致:比如用
std::less排序,就别用==去手动校验
std::set 再查。











