Since concepts are defined as compile-time predicates, is it also possible to actually reuse these predicates for compile-time algorithms? For example would it be possible to check whether all types in a tuple conform to a concept? As far as I have seen it is not possible to pass a concept to a function in any way, which kind of leads me back to using templates for these cases.
#include <type_traits>
template<typename T>
concept FloatLike = std::is_same_v<T, float>;
struct IsFloat
{
template<typename U>
constexpr static bool test()
{
return FloatLike<U>;
}
};
template<typename Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate::template test<T>() && ...);
}
int main()
{
static_assert(all_types<IsFloat, float, float>());
static_assert(!all_types<IsFloat, float, int>());
}
What I would like to do is something like this, so I don't have to wrap the concept all the time to be able to use it:
template<concept Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate<T> && ...);
}
int main()
{
static_assert(all_types<FloatLike, float, float>());
static_assert(!all_types<FloatLike, float, int>());
}
Is there any way to get closer to this?
Function Call When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this: func(print); would call func , passing the print function to it.
“Passing by value” refers to passing a copy of the value. “Passing by reference” refers to passing the real reference of the variable in memory.
Parameters are essential to functions, because otherwise you can't give the function-machine an input.
Is there any way to get closer to this?
Well, no, not really. Not in C++20. There is no notion in the language today of a template concept-parameter. Even variable templates cannot be used as template parameters. So if have a concept to begin with, we can't avoid wrapping.
But what we can do is write simpler wrappers. If we agree to use "old style" type traits as predicates, specifically those that behave like std::integral_constant
s, then we can have ourselves pretty terse "concept" definitions that can be used as predicates.
template<typename T>
using FloatLike = std::is_same<T, float>;
template<template <typename> class Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate<T>{} && ...);
}
It's as good as it can get, as far as I can see.
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