每周技巧 #158:Abseil 关联容器和 `contains()`
本节阅读量:本文翻译自 Abseil 官网的 Tip of the Week #158: Abseil Associative containers and contains()。
原文最初作为 TotW #158 发布于 2019 年 1 月 3 日。
更新于 2020 年 4 月 20 日。
快捷链接:abseil.io/tips/158
“我无法克制自己。” —— Bertrand Russell
那个容器到底包含这个东西吗?
检查 set 是否包含某个值,或 map 是否包含某个 key 时,C++ 历史上迫使用户在相当啰嗦的写法:
|
|
和可以说有些晦涩(有时还低效)的写法之间选择:
|
|
而不是写我们想写的:
|
|
container.contains(value) 来救场
这个更简单的语法是 C++20 标准的一部分,而 Abseil 的哈希容器(absl::{flat,node}_hash_{map,set})和 btree 容器(absl::btree_*)今天已经支持它。
contains 和 find 一样支持异构查找,所以(例如)可以检查 absl::flat_hash_set<std::string> 是否包含一个 absl::string_view 值,而不必付出转换为 std::string 对象的成本:
|
|
鉴于我们大多数需要关联容器(无论 set 还是 map)的代码现在都应该使用 Abseil 哈希容器(见 技巧 #136),新代码中很少需要使用其他写法。
注意:如 技巧 #132(“避免冗余的 map 查找”)所述,不要先检查某项是否在容器中,然后再做另一个隐含查找的操作(例如 find、insert 或 remove)。
结论
查询某个项是否能在关联容器中找到,是常见操作;它的自然语法是 container.contains(value)。可用时优先使用这个语法。
本节目录