cpp/language/constraints


 * This page describes the core language feature adopted for C++20. For named type requirements used in the specification of the standard library, see named requirements. For the Concepts TS version of this feature, see here.

, s, and non-template functions (typically members of class templates) may be associated with a constraint, which specifies the requirements on template arguments, which can be used to select the most appropriate function overloads and template specializations.

Named sets of such are called concepts. Each concept is a predicate, evaluated at compile time, and becomes a part of the interface of a template where it is used as a constraint:

Violations of constraints are detected at compile time, early in the template instantiation process, which leads to easy to follow error messages:

The intent of concepts is to model semantic categories (Number, Range, RegularFunction) rather than syntactic restrictions (HasPlus, Array). According to ISO C++ core guideline T.20, "The ability to specify meaningful semantics is a defining characteristic of a true concept, as opposed to a syntactic constraint."

Concepts
A concept is a named set of. The definition of a concept must appear at namespace scope.

The definition of a concept has the form

Concepts cannot recursively refer to themselves and cannot be constrained:

Explicit instantiations, explicit specializations, or partial specializations of concepts are not allowed (the meaning of the original definition of a constraint cannot be changed).

Concepts can be named in an id-expression. The value of the id-expression is if the constraint expression is satisfied, and  otherwise.

Concepts can also be named in a type-constraint, as part of


 * compound requirement.
 * compound requirement.
 * compound requirement.

In a, a concept takes one less template argument than its parameter list demands, because the contextually deduced type is implicitly used as the first argument of the concept.

Constraints
A constraint is a sequence of logical operations and operands that specifies requirements on template arguments. They can appear within requires expressions or directly as bodies of concepts.

There are three types of constraints: @1@ conjunctions @2@ disjunctions @3@ atomic constraints

The constraint associated with a declaration are determined by normalizing a logical AND expression whose operands are in the following order:
 * 1) the constraint expression introduced for each constrained  or non-type template parameter declared with a constrained, in order of appearance;
 * 2) the constraint expression in the  after the template parameter list;
 * 3) the constraint expression introduced for each parameter with constrained  in an ;
 * 4) the constraint expression in the trailing.

This order determines the order in which constraints are instantiated when checking for satisfaction.

Redeclarations
A constrained declaration may only be redeclared using the same syntactic form. No diagnostic is required:

Conjunctions
The conjunction of two constraints is formed by using the operator in the constraint expression:

A conjunction of two constraints is satisfied only if both constraints are satisfied. Conjunctions are evaluated left to right and short-circuited (if the left constraint is not satisfied, template argument substitution into the right constraint is not attempted: this prevents failures due to substitution outside of immediate context).

Disjunctions
The disjunction of two constraints is formed by using the operator in the constraint expression.

A disjunction of two constraints is satisfied if either constraint is satisfied. Disjunctions are evaluated left to right and short-circuited (if the left constraint is satisfied, template argument substitution into the right constraint is not attempted).

Atomic constraints
An atomic constraint consists of an expression and a mapping from the template parameters that appear within  to template arguments involving the template parameters of the constrained entity, called its parameter mapping.

Atomic constraints are formed during constraint normalization. is never a logical AND or logical OR expression (those form conjunctions and disjunctions, respectively).

Satisfaction of an atomic constraint is checked by substituting the parameter mapping and template arguments into the expression. If the substitution results in an invalid type or expression, the constraint is not satisfied. Otherwise,, after any lvalue-to-rvalue conversion, shall be a prvalue constant expression of type , and the constraint is satisfied if and only if it evaluates to.

The type of after substitution must be exactly. No conversion is permitted:

Two atomic constraints are considered identical if they are formed from the same expression at the source level and their parameter mappings are equivalent.

Constraint normalization
Constraint normalization is the process that transforms a constraint expression into a sequence of conjunctions and disjunctions of atomic constraints. The normal form of an expression is defined as follows:
 * The normal form of an expression is the normal form of ;
 * The normal form of an expression is the conjunction of the normal forms of  and.
 * The normal form of an expression is the disjunction of the normal forms of  and.
 * The normal form of an expression, where names a concept, is the normal form of the constraint expression of , after substituting A1, A2, ... , AN for 's respective template parameters in the parameter mappings of each atomic constraint of C. If any such substitution into the parameter mappings results in an invalid type or expression, the program is ill-formed, no diagnostic required.


 * The normal form of any other expression is the atomic constraint whose expression is  and whose parameter mapping is the identity mapping. This includes all, even those folding over the  or  operators.

User-defined overloads of or  have no effect on constraint normalization.

Requires clauses
The keyword is used to introduce a requires-clause, which specifies constraints on template arguments or on a function declaration.

In this case, the keyword requires must be followed by some constant expression (so it's possible to write ), but the intent is that a named concept (as in the example above) or a conjunction/disjunction of named concepts or a is used.

The expression must have one of the following forms:
 * a, e.g. , , , or any parenthesized expression
 * a sequence of primary expressions joined with the operator
 * a sequence of aforementioned expressions joined with the operator

Partial ordering of constraints
Before any further analysis, constraints are normalized by substituting the body of every named concept and every until what is left is a sequence of conjunctions and disjunctions on atomic constraints.

A constraint is said to subsume constraint  if it can be proven that  implies  up to the identity of atomic constraints in P and Q. (Types and expressions are not analyzed for equivalence:  does not subsume ).

Specifically, first is converted to disjunctive normal form and  is converted to conjunctive normal form. subsumes if and only if:
 * every disjunctive clause in the disjunctive normal form of subsumes every conjunctive clause in the conjunctive normal form of, where
 * a disjunctive clause subsumes a conjunctive clause if and only if there is an atomic constraint in the disjunctive clause and an atomic constraint  in the conjunctive clause such that  subsumes ;
 * an atomic constraint subsumes an atomic constraint  if and only if they are identical using the rules described above.

Subsumption relationship defines partial order of constraints, which is used to determine:
 * the best viable candidate for a non-template function in
 * the in an overload set
 * the best match for a template template argument
 * partial ordering of class template specializations
 * of function templates

If declarations and  are constrained and 's associated constraints subsume 's associated constraints (or if  is unconstrained), then  is said to be at least as constrained as. If is at least as constrained as, and  is not at least as constrained as , then  is more constrained than.

Keywords
,