简体   繁体   中英

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}
};

can we use std::any_of on this map to see any of its values is false ? Or any of its key is let's say "d" ?

Similarly can we use std::all_of or std::none_of on this map?

The simplest solution is to use a 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; });

Here the lambda expression [](...) { ... } is a unary predicate that takes const auto& p and makes the test. const auto& will be deduced to const std::pair<const std::string, bool>& (= std::unordered_map<...>::value_type ), that's why you use .second to test the bool part of a pair. Use .first member to test the element's key.

Quick answer: What happens when you try?

Another quick answer: Yes

Reason: Looking at this page we can see that std::all_of and friends expect that:

InputIt must meet the requirements of LegacyInputIterator .

Now, std::map.begin() returns a LegacyBidirectionalIterator

Finally, looking at the table here we can see that LegacyBidirectionalIterator is a kind of LegacyInputIterator , so therefore you can use an std::map with std::all_of and friends.

Iterating over a map yields key-value pairs. So you can just pass a lambda to the algorithm to unpack the key value pair.

To check a val, use .second :

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

To check keys, use .first :

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

Live code 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;
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM