...

/

Syntactic Overview of Constraints and Concepts

Syntactic Overview of Constraints and Concepts

Learn about concepts and constraints in coding, including function overloading and standard library concepts.

This section is a short introduction to constraints and concepts. We will not cover them completely in this course, but we will provide enough material to be productive.

Defining new concepts

Defining new concepts is straightforward with some help from the type traits that you are already familiar with. The following example defines the concept FloatingPoint using the keyword concept:

Press + to interact
template <typename T>
concept FloatingPoint = std::is_floating_point_v<T>;

The right-hand side of the assignment expression is where we can specify the constraints of the type T. Combining multiple constraints using || (logical OR*) and && (logical AND) is also possible. The following example uses || to combine floats and integrals into a Number concept:

Press + to interact
template <typename T>
concept Number = FloatingPoint<T> || std::is_integral_v<T>;

We will note that it’s possible to build concepts using already defined concepts on the right-hand side as well. The standard library contains a <concepts> header, which defines many useful concepts, such as std::floating_point (which we should use rather than define ourselves).

Furthermore, we can use the requires keyword to add a set of statements that should be added to our concept definition. For example, this is the definition of the concept std::range from the Ranges library:

Press + to interact
template <typename T>
concept Range = requires(T& t) {
begin(t);
end(t);
};

In short, this concept states that a range is something that we can pass to std::ranges::begin() and std::ranges::end().

It’s possible to write more sophisticated requires clauses than ...