NoSenseEtAl
NoSenseEtAl

Reputation: 30048

Do C++20 ranges have value(not predicate) version of filter or any_of?

Classic C++ sometimes picks the _if suffix for predicate algorithms(versus the ones that take value) e.g. find_if/find count_if/count and sometimes it does not(for example any_of does not have _if suffix although it takes predicate, and there is no any_of value version of algorithm).

As far as I can see C++20 filter or ranges::any_of have no value overload.

I went through entire cppreference page for C+++20 and found nothing, I presume it was just because C++20 ranges library is quite limited (only few views) and it is matching existing functionality (in case of any_of).

My best attempt is to just wrap the logic and give it a new name.

template <typename Range, typename Value>
static bool contains(const Range& range, const Value& value)
{
    return std::ranges::find(range, value) != range.end();
}

edit: good news: C++23 has std::ranges::contains

Upvotes: 5

Views: 2541

Answers (1)

Barry
Barry

Reputation: 303186

Do C++20 ranges have value(not predicate) version of filter or any_of?

No, C++20 does not. But it is pretty easy to write:

std::ranges::any_of(r, [&](auto const& e){ return e == value; })

Thankfully, C++23 does introduce a new ranges::contains to make this even easier:

std::ranges::contains(r, value);

Or, if that is considered too long, you could add a helper:

inline constexpr auto equals = [](auto const& value){
    return [=](auto const& e){ return e == value; };
};

That you can use to shorten the any_of call:

std::ranges::any_of(r, equals(value));

Or you could use any number of libraries that let you write placeholder-lambdas, most recently Boost.Lambda2:

std::ranges::any_of(r, _1 == value);

Upvotes: 12

Related Questions