Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can concepts be used to put a constraint on values as well as types?

Concepts can be used to put a constraint on types as template parameters like the example below:

template<typename t, int v>
concept the_concept1 = sizeof(t) > v;

template<int v, the_concept1<v> t>
struct some_struct1{};

I am trying to use a similar method with values like the example below:

template<int v1, int v2>
concept the_concept2 = v1 > v2;

template<int v1, the_concept2<v1> v2>
struct some_struct2{};

But with G++ 10 I am getting the following error message:

error: ‘the_concept2’ does not constrain a type

So I was wondering if concepts can be used to put a constraint on values? If so then how should I do it?

Edit: My final goal is to use the concept in declaration of a template structure with variadic template parameters like:

template<typename t, std::size_t ... v>
struct the_struct;

And I need a concept to check if every v is less than sizeof(t).

like image 261
AKL Avatar asked Sep 18 '20 08:09

AKL


People also ask

What are concepts Cpp?

Concepts are a revolutionary approach for writing templates! They allow you to put constraints on template parameters that improve the readability of code, speed up compilation time, and give better error messages. Read on and learn how to use them in your code!

What are constraints in c++?

A constraint is a requirement that types used as type arguments must satisfy. For example, a constraint might be that the type argument must implement a certain interface or inherit from a specific class. Constraints are optional; not specifying a constraint on a parameter is equivalent to using a Object constraint.

What is concept in c++ 20?

Writing conceptsConstraint expression can contain constexpr boolean expressions, conjunction/disjunction of other concepts and requires blocks. So for our previous example, we could construct a boolean expression using C++11 type traits or construct a compound concept from C++20 standard library concepts.


1 Answers

If you want to use a concept as a named type constraint on a template parameter, as in your example, the concept needs to apply to a type template parameter.

You can still define concepts that apply only to e.g. non-type template parameters, however, as long as you use it in a context which allows these; e.g. using a requires-clause:

template<int v1, int v2>
concept the_concept2 = v1 > v2;

template<int v1, int v2> requires the_concept2<v1, v2>
struct some_struct2{};

using valid = some_struct2<42, 41>;
//using invalid = some_struct2<42, 42>; // constraints not satisfied

Another example applied on a function template or a member function of a class template:

template<int v1, int v2>
concept the_concept2 = v1 > v2;

template <int a, int b>
void bar() requires the_concept2<a, b> {} 

template <int a, int b>
struct Foo {
    static void bar() requires the_concept2<a, b> {} 
};

int main() {
    bar<2, 1>();
    Foo<2, 1>::bar();
    //bar<2, 2>();      // candidate template ignored: constraints not satisfied
    //Foo<2, 2>::bar(); // invalid reference to function 'bar': constraints not satisfied
}

The following OP edit (which basically asks an entirely different question)

Edit: My final goal is to use the concept in declaration of a template structure with variadic template parameters like:

template<typename t, std::size_t ... v>
struct the_struct;

And I need a concept to check if every v is less than sizeof(t).

can be achieved by specifying the concept itself to apply for variadic non-type template parameters that are expanded in the sizeof(T) > v check using parameter pack expansion:

#include <cstddef>
#include <cstdint>

template<typename T, std::size_t... v>
concept the_concept1 = (... && (sizeof(T) > v));

template<typename T, std::size_t... vs> requires the_concept1<T, vs...>
struct the_struct;

using TypeOfSize4Bytes = uint32_t;

using valid = the_struct<TypeOfSize4Bytes, 1, 3, 2, 1>;
using also_valid = the_struct<TypeOfSize4Bytes>;
//using invalid = the_struct<TypeOfSize4Bytes, 1, 2, 4>;  // error: constraints not satisfied
like image 70
dfrib Avatar answered Oct 07 '22 00:10

dfrib