std::ranges::contains
std::ranges::contains
是 C++23 中引入的一个算法,用于检查一个范围中是否包含指定的值。它属于 <algorithm>
头文件,是范围库(Ranges Library)的一部分,提供更简洁、安全的范围操作。
Call signature | ||
(1) | ||
template< std::input_iterator I, std::sentinel_for<I> S, class T, | (since C++23) (until C++26) | |
template< std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity, | (since C++26) | |
(2) | ||
template< ranges::input_range R, class T, | (since C++23) (until C++26) | |
template< ranges::input_range R, class Proj = std::identity, | (since C++26) | |
template< std::forward_iterator I1, std::sentinel_for<I1> S1, std::forward_iterator I2, std::sentinel_for<I2> S2, | (3) | (since C++23) |
template< ranges::forward_range R1, ranges::forward_range R2, class Pred = ranges::equal_to, |
- 参数:
r
:要检查的输入范围。value
:要查找的值。proj
:投影函数(可选),用于对范围中的元素进行转换后再比较。
- 返回值:
- 如果范围中存在等于
value
的元素,返回true
;否则返回false
。
- 如果范围中存在等于
关键点
- 线性搜索:从范围起点开始逐个检查元素,直到找到目标值或遍历完整个范围。
- 复杂度:时间复杂度为 O(N),空间复杂度为 O(1)。
- 投影支持:允许通过
proj
对元素进行转换后再比较(例如查找对象的某个成员)。 - 范围安全性:直接操作范围,避免裸指针和迭代器的手动管理。
示例
示例 1:基本用法
#include <algorithm>
#include <vector>
#include <ranges>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 检查是否包含 3
bool has_3 = std::ranges::contains(v, 3);
std::cout << "Contains 3: " << has_3 << std::endl; // 输出 1(true)
// 检查是否包含 6
bool has_6 = std::ranges::contains(v, 6);
std::cout << "Contains 6: " << has_6 << std::endl; // 输出 0(false)
}
输出:
Contains 3: 1
Contains 6: 0
示例 2:使用投影函数
#include <algorithm>
#include <vector>
#include <ranges>
#include <iostream>
struct Person {
std::string name;
int age;
};
int main() {
std::vector<Person> people = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35}
};
// 检查是否存在年龄为 30 的人
bool has_age_30 = std::ranges::contains(
people,
30,
[](const Person& p) { return p.age; } // 投影:提取 age 成员
);
std::cout << "Has age 30: " << has_age_30 << std::endl; // 输出 1(true)
}
输出:
Has age 30: 1
应用场景
- 简单存在性检查:快速判断某个值是否在集合中。
- 条件过滤:结合投影函数检查对象成员的特定值。
- 字符串处理:检查字符或子字符串是否存在。
注意事项
- C++23 支持:需确保编译器支持 C++23(如 GCC 13+、Clang 16+、MSVC 19.30+)。
- 性能:对于大规模数据,线性搜索可能不够高效,此时建议使用
std::ranges::binary_search
(需先排序)
如下container有自己的contains:
std::map::contains
std::set::contains
std::multimap::contains
std::multiset::contains
std::unordered_map::contains
std::unordered_set::contains
std::unordered_multimap::contains
std::unordered_multiset::contains
std::string::contains C++23
std::array 和 std::vector没有定义contains,只能使用std::ranges::contains, STL并没有提供std::contains。