7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.7 Requires expressions [expr.prim.req] Compound requirements [expr.prim.req.compound]

A compound-requirement asserts properties of the expression E.
Substitution of template arguments (if any) and verification of semantic properties proceed in the following order:
  • Substitution of template arguments (if any) into the expression is performed.
  • If the noexcept specifier is present, E shall not be a potentially-throwing expression ([except.spec]).
  • If the return-type-requirement is present, then:
    • Substitution of template arguments (if any) into the return-type-requirement is performed.
    • The immediately-declared constraint ([temp.param]) of the type-constraint for decltype((E)) shall be satisfied.
      [Example 1:
      Given concepts C and D, requires { { E1 } -> C; { E2 } -> D<A, , A>; }; is equivalent to requires { E1; requires C<decltype((E1))>; E2; requires D<decltype((E2)), A, , A>; }; (including in the case where n is zero).
      — end example]
[Example 2: template<typename T> concept C1 = requires(T x) { {x++}; };
The compound-requirement in C1 requires that x++ is a valid expression.
It is equivalent to the simple-requirement x++;.
template<typename T> concept C2 = requires(T x) { {*x} -> std::same_­as<typename T::inner>; };
The compound-requirement in C2 requires that *x is a valid expression, that typename T​::​inner is a valid type, and that std​::​same_­as<decltype((*x)), typename T​::​inner> is satisfied.
template<typename T> concept C3 = requires(T x) { {g(x)} noexcept; };
The compound-requirement in C3 requires that g(x) is a valid expression and that g(x) is non-throwing.
— end example]