std::map::contains是C++20新增函数,用于简洁安全地判断key是否存在,仅适用于有序关联容器;unordered_map仍需用find或count,不可用operator[]。

std::map::contains 是 C++20 新增的成员函数
直接用 contains 判断 key 是否存在,比 find != end() 更简洁、语义更清晰,且不触发 value_type 的构造(对非默认可构造类型更安全)。
它只适用于有序关联容器(std::map、std::set、std::multimap、std::multiset),不适用于 std::unordered_map 等哈希容器(C++20 也没给它们加 contains)。
std::map<int, std::string> m = {{1, "a"}, {2, "b"}};-
m.contains(1)→true -
m.contains(3)→false
unordered_map 怎么判断 key 存在(C++20 仍无 contains)
std::unordered_map 在 C++20 中依然没有 contains 成员函数,必须继续用 find 或 count。
-
find:推荐,O(1) 平均复杂度,返回迭代器,适合后续可能取值的场景 -
count:也 O(1),但对std::multimap/std::multiset才有意义;对unordered_map它只能返回 0 或 1,不如find直观 - 别用
operator[]判断——会默认构造 value(如std::vector<int>被默认初始化为空),副作用大
示例:auto it = umap.find(key); if (it != umap.end()) { /* exists */ }
立即学习“C++免费学习笔记(深入)”;
contains 和 find 的性能与语义差异
对 std::map 这类红黑树容器,contains 和 find 都是 O(log n),底层通常复用同一查找逻辑,性能几乎无差别。
-
contains只返回bool,不暴露迭代器,避免误用(比如对 end() 迭代器解引用) -
find返回迭代器,适合“查完立刻读/改 value”的场景 - 若你只需要判断存在性,且用的是 C++20+ 的
map或set,优先写contains——代码更短,意图更明确
编译器支持和 fallback 写法
Clang 10+、GCC 10+、MSVC 19.28+ 支持 std::map::contains,但需显式启用 C++20(如 -std=c++20)。
若项目暂不能升 C++20,或需兼容旧标准,可用宏封装:
#if __cpp_lib_map_contains >= 201806L
if (m.contains(key)) { ... }
#else
if (m.find(key) != m.end()) { ... }
#endif注意:__cpp_lib_map_contains 是特性测试宏,比检查语言标准版本更准确;别只靠 __cplusplus == 202002L 判断。
真正容易被忽略的是:contains 不解决自定义比较器导致的等价性陷阱——如果你重载了 operator< 或传了自定义 Compare,确保 key 的等价判断逻辑和容器一致,否则 contains 结果可能不符合预期。


















