This works, but is it legal/safe?
(i.e.: Is it okay to pass projection as predicate argument to std::ranges::any_of/all_of/none_of?)
#include <ranges>
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
struct boo{
bool b;
bool get(){ return b; }
};
std::vector<boo> bools{ {0}, {0}, {0}, {1}, {0} };
if(std::ranges::any_of(bools, &boo::b )){
std::cout << "&boo::b\n";
}
if(std::ranges::any_of(bools, &boo::get )){
std::cout << "&boo::get\n";
}
// check for non zero ptr
const char *ptrs[6]{0, 0, 0, "0", 0, 0};
if(std::ranges::any_of(ptrs, std::identity{} )){
std::cout << "std::identity{}\n";
}
}
Godbolt
A predicate is roughly speaking a callable that returns a bool when called.
It's OK to pass your projections here for the predicate (pred) parameter because they return a bool (it could also be something convertible to bool).
If your projection was returning something which is not convertible to bool it will no longer compile.
For example:
struct NoBool {};
struct boo {
NoBool b;
NoBool get() { return b; }
};
std::vector<boo> bools{ {}, {}, {}, {}, {} };
if (std::ranges::any_of(bools, &boo::b)) {
std::cout << "&boo::b\n";
}
if (std::ranges::any_of(bools, &boo::get)) {
std::cout << "&boo::get\n";
}
Will cause compiler errors for both above calls of std::ranges::any_of:
<source>:17:31: error: no match for call to '(const std::ranges::__any_of_fn) (std::vector<main()::boo>&, main()::NoBool main()::boo::*)'
17 | if(std::ranges::any_of(bools, &boo::b )){
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
...
Live demo - Godbolt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With