Defining concepts
The constraints seen previously are nameless predicates defined in the places they are used. Many constraints are generic and can be used in multiple places. Let’s consider the following example of a function similar to the add function. This function performs the multiplication of arithmetic values and is shown next:
template <typename T>
requires std::is_arithmetic_v<T>
T mul(T const a, T const b)
{
   return a * b;
}
The same requires clause seen with the add function is present here. To avoid this repetitive code, we can define a name constraint that can be reused in multiple places. A named constraint is called a concept. A concept is defined with the new concept keyword and template syntax. Here is an example:
template<typename T> concept arithmetic = std::is_arithmetic_v<T>;
Even though they are assigned a Boolean value, concept names should not contain verbs. They represent requirements and are used...