[expr.prim.req.general]

# 7 Expressions [[expr]](./#expr)

## 7.5 Primary expressions [[expr.prim]](expr.prim#req.general)

### 7.5.8 Requires expressions [[expr.prim.req]](expr.prim.req#general)

#### 7.5.8.1 General [expr.prim.req.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3193)

A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") provides a concise way to express
requirements on template arguments
that can be checked by [name lookup](basic.lookup "6.5 Name lookup [basic.lookup]") or by checking properties of types and expressions[.](#1.sentence-1)

[requires-expression:](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")  
requires [*requirement-parameter-list*](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]")opt [*requirement-body*](#nt:requirement-body "7.5.8.1 General [expr.prim.req.general]")

[requirement-parameter-list:](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]")  
( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") )

[requirement-body:](#nt:requirement-body "7.5.8.1 General [expr.prim.req.general]")  
{ [*requirement-seq*](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]") }

[requirement-seq:](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]")  
[*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") [*requirement-seq*](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]")opt

[requirement:](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")  
[*simple-requirement*](expr.prim.req.simple#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]")  
[*type-requirement*](expr.prim.req.type#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]")  
[*compound-requirement*](expr.prim.req.compound#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]")  
[*nested-requirement*](expr.prim.req.nested#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]")

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3228)

A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") is a prvalue of type bool whose value is described below[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3232)

[*Example [1](#example-1)*:

A common use of [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")*s* 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](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const typename T::type&>; };

A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") can also be used in a[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble")) 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*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]"), and the second
introduces the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")[.](#3.sentence-3)

â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3256)

A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") may introduce local parameters using a[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")[.](#4.sentence-1)

A local parameter of a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") shall not have a
default argument[.](#4.sentence-2)

The type of such a parameter is determined as specified for
a function parameter in [[dcl.fct]](dcl.fct "9.3.4.6 Functions")[.](#4.sentence-3)

These parameters have no linkage, storage, or lifetime; they are only used
as notation for the purpose of defining [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*[.](#4.sentence-4)

The [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of a[*requirement-parameter-list*](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]") shall not terminate with an ellipsis[.](#4.sentence-5)

[*Example [2](#example-2)*: template<typename T>concept C = requires(T t, ...) { // error: terminates with an ellipsis t;};template<typename T>concept C2 = requires(T p[2]) {(decltype(p))nullptr; // OK, p has type âpointer to T''}; â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3281)

The substitution of template arguments into a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") can result in
the formation of invalid types or expressions in the immediate context of
its [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s* ([[temp.deduct.general]](temp.deduct.general "13.10.3.1 General")) or
the violation of the semantic constraints of those [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*[.](#5.sentence-1)

In such cases, the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") evaluates to false;
it does not cause the program to be ill-formed[.](#5.sentence-2)

The substitution and semantic constraint checking
proceeds in lexical order and stops when a condition that
determines the result of the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") is encountered[.](#5.sentence-3)

If substitution (if any) and semantic constraint checking succeed,
the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") evaluates to true[.](#5.sentence-4)

[*Note [1](#note-1)*:

If a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") contains invalid types or expressions in
its [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*, and it does not appear within the declaration of a templated
entity, then the program is ill-formed[.](#5.sentence-5)

â *end note*]

If the substitution of template arguments into a [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") would always result in a substitution failure, the program is ill-formed;
no diagnostic required[.](#5.sentence-6)

[*Example [3](#example-3)*: template<typename T> concept C =requires {new decltype((void)T{}); // ill-formed, no diagnostic required}; â *end example*]
