7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.7 Requires expressions [expr.prim.req]

7.5.7.1 General [expr.prim.req.general]

A requires-expression provides a concise way to express requirements on template arguments that can be checked by name lookup or by checking properties of types and expressions.
A requires-expression is a prvalue of type bool whose value is described below.
Expressions appearing within a requirement-body are unevaluated operands.
[Example 1:
A common use of requires-expressions is to define requirements in concepts such as the one below: template<typename T> concept R = requires (T i) { typename T::type; {*i} -> std::convertible_­to<const typename T::type&>; };
A requires-expression can also be used in a requires-clause ([temp.pre]) as a way of writing ad hoc constraints on template arguments such as the one below: template<typename T> requires requires (T x) { x + x; } T add(T a, T b) { return a + b; }
The first requires introduces the requires-clause, and the second introduces the requires-expression.
— end example]
A requires-expression may introduce local parameters using a parameter-declaration-clause ([dcl.fct]).
A local parameter of a requires-expression shall not have a default argument.
Each name introduced by a local parameter is in scope from the point of its declaration until the closing brace of the requirement-body.
These parameters have no linkage, storage, or lifetime; they are only used as notation for the purpose of defining requirements.
The parameter-declaration-clause of a requirement-parameter-list shall not terminate with an ellipsis.
[Example 2: template<typename T> concept C = requires(T t, ...) { // error: terminates with an ellipsis t; }; — end example]
The requirement-body contains a sequence of requirements.
These requirements may refer to local parameters, template parameters, and any other declarations visible from the enclosing context.
The substitution of template arguments into a requires-expression may result in the formation of invalid types or expressions in its requirements or the violation of the semantic constraints of those requirements.
In such cases, the requires-expression evaluates to false; it does not cause the program to be ill-formed.
The substitution and semantic constraint checking proceeds in lexical order and stops when a condition that determines the result of the requires-expression is encountered.
If substitution (if any) and semantic constraint checking succeed, the requires-expression evaluates to true.
[Note 1:
If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed.
— end note]
If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.
[Example 3: template<typename T> concept C = requires { new int[-(int)sizeof(T)]; // ill-formed, no diagnostic required }; — end example]