8 Statements [stmt]

8.7 Expansion statements [stmt.expand]

Expansion statements specify repeated instantiations ([temp.decls.general]) of their substatement.
The compound-statement of an expansion-statement is a control-flow-limited statement ([stmt.label]).
For an expression E, let the expressions begin-expr and end-expr be determined as specified in [stmt.ranged].
An expression is expansion-iterable if it does not have array type and either
  • begin-expr and end-expr are of the form E.begin() and E.end() or
  • argument-dependent lookups for begin(E) and for end(E) each find at least one function or function template.
An expansion statement is
An expansion statement S is equivalent to a compound-statement containing instantiations of the for-range-declaration (including its implied initialization), together with the compound-statement of S, as follows:
[Example 1: consteval int f(auto const&... Containers) { int result = 0; template for (auto const& c : {Containers...}) { // OK, enumerating expansion statement result += c[0]; } return result; } constexpr int c1[] = {1, 2, 3}; constexpr int c2[] = {4, 3, 2, 1}; static_assert(f(c1, c2) == 5); — end example]
[Example 2: consteval int f() { constexpr std::array<int, 3> arr {1, 2, 3}; int result = 0; template for (constexpr int s : arr) { // OK, iterating expansion statement result += sizeof(char[s]); } return result; } static_assert(f() == 6); — end example]
[Example 3: struct S { int i; short s; }; consteval long f(S s) { long result = 0; template for (auto x : s) { // OK, destructuring expansion statement result += sizeof(x); } return result; } static_assert(f(S{}) == sizeof(int) + sizeof(short)); — end example]