Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a concept to a function

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?

like image 526
Andreas Loanjoe Avatar asked Nov 15 '19 11:11

Andreas Loanjoe


People also ask

How do you pass a function?

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.

What is passing by reference vs passing by value?

“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.

Why do we pass parameters in function?

Parameters are essential to functions, because otherwise you can't give the function-machine an input.


1 Answers

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_constants, 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.

like image 185
StoryTeller - Unslander Monica Avatar answered Sep 29 '22 03:09

StoryTeller - Unslander Monica