I am trying to constrain a Callable to return a boolean when evaluated. I have been trying to use the concept std::predicate
, but it does not seem to do what I want it to do.
So I defined my own concept, that is invokable and returns something convertible to a boolean. But again, I struggle understanding what I can or can not do with it, and I wonder what are the actual use cases of std::predicate
?
#include<concepts>
#include<string>
template<class F, class... Args>
concept Predicate = std::invocable<F, Args...> &&
std::convertible_to<std::invoke_result_t<F, Args...>, bool>;
int main(int argc, char *argv[])
{
constexpr Predicate auto f1 = [](){return true;}; // ok
constexpr std::predicate auto f2 = [](){return true;}; // ok
constexpr int x = 34;
constexpr Predicate auto f3 = [x](){ return x==42;}; // ok
// Pas ok: error: deduced initializer does not satisfy placeholder constraints
//constexpr Predicate auto f4 = [](auto x){ return x==42;};
//constexpr std::predicate auto f5 = [](auto x){ return x==42;};
}
CodePudding user response:
You cannot have a function that takes a "thing that can be called". It must be a "thing that can be called with some set of arguments of known (at the time of the declaration) types". That's why std::predicate
takes a set of arguments in addition to the potential callable type.
Your first examples work because you didn't give the predicate concept any arguments and your functions also didn't take any parameters. So an empty argument list matches the empty parameter list.