将 std::any_of、std::all_of、std::none_of 等与 std::map 一起使用

Using std::any_of, std::all_of, std::none_of etc with std::map

std::unordered_map<std::string, bool> str_bool_map = {
    {"a", true},
    {"b", false},
    {"c", true}
};

我们可以在这张地图上使用 std::any_of 来查看它的任何值是 false 吗?或者它的任何关键是 "d"?

同样我们可以在这张地图上使用std::all_ofstd::none_of吗?

最简单的解决方案是使用 lambda:

std::unordered_map<std::string, bool> str_bool_map = 
    {{"a", true}, {"b", false}, {"c", true}};

bool f = std::any_of(str_bool_map.begin(), str_bool_map.end(),
    [](const auto& p) { return !p.second; });

这里的 lambda 表达式 [](...) { ... } 是一个一元谓词,接受 const auto& p 并进行测试。 const auto& 将推导为 const std::pair<const std::string, bool>& (= std::unordered_map<...>::value_type),这就是为什么您使用 .second 来测试一对中的 bool 部分。使用 .first 成员来测试元素的键。

遍历映射会产生键值对。因此,您只需将 lambda 传递给算法即可解压缩键值对。

要检查一个值,使用.second:

std::any_of(m.begin(), m.end(), [](const auto& kvp){ return kvp.second; });

要检查密钥,请使用 .first:

std::any_of(m.begin(), m.end(), [](const auto& kvp){ return kvp.first == "d"; }) 

实时代码here.

#include <algorithm>
#include <map>

int main()
{
    std::map<std::string, bool> map;
    map["foo"] = false;
    map["bar"] = true;
    map["baz"] = false;

    const bool any = std::any_of(map.begin(), map.end(), [](const auto& pair)
    {
        return !pair.second;
    });

    const bool all = std::all_of(map.begin(), map.end(), [](const auto& pair)
    {
        return !pair.second;
    });

    const bool none_of = std::none_of(map.begin(), map.end(), [](const auto& pair)
    {
        return !pair.second;
    });
}

快速回答:尝试时会发生什么?

另一个快速回答:是

原因:查看 this page 我们可以看到 std::all_of 并且朋友们期望:

InputIt must meet the requirements of LegacyInputIterator.

现在,std::map.begin() returns一个LegacyBidirectionalIterator

最后,查看 the table here 我们可以看到 LegacyBidirectionalIterator 是一种 LegacyInputIterator,因此您可以使用std::mapstd::all_of 和朋友。