...

/

Composing Constraints

Composing Constraints

Take your knowledge of constraints to the next level by performing conjunctions and disjunctions on constraints.

We have seen multiple examples of constraining template arguments, but in all the cases so far, we used a single constraint. It’s possible, though, for constraints to be composed using the && and || operators. A composition of two constraints using the && operator is called a conjunction and the composition of two constraints using the || operator is called a disjunction.

Constraint conjunctions

For a conjunction to be true, both constraints must be true. Like in the case of logical AND operations, the two constraints are evaluated from left to right, and if the left constraint is false, the right constraint is not evaluated. Let’s look at an example:

template<typename T>
requires std::is_integral_v<T> && std::is_signed_v<T>
T decrement(T value)
{
return value--;
}
Performing constraint conjunction using requires expression

In this snippet, we have a function template that returns the decremented value of the received argument. However, it only accepts signed integral values. This is specified with the conjunction of two constraints, std::is_integral_v<T> && std::is_ signed_v<T>. The same result can be achieved using a different approach to defining the conjunction, as shown next:

template<typename T>
concept Integral = std::is_integral_v<T>;
template<typename T>
concept Signed = std::is_signed_v<T>;
template<typename T>
concept SignedIntegral = Integral<T> && Signed<T>;
template<SignedIngeral T>
T decrement(T value)
{
return value--;
}
Performing constraint conjunction using concepts

We can see three ...