Title
Global lookup for begin and end for expansion statements
Status
review
Section
8.7 [stmt.expand]
Submitter
Ambrose T.

Created on 2025-11-11.00:00:00 last changed 1 month ago

Messages

Date: 2026-01-23.22:56:25

Additional notes (CWG 2026-01-23)

There is agreement that std::tuple should not be considered expansion-iterable, and the proposed resolution achieves that goal. However, the proposed resolution can also cause additional template instantiations, which might be needed to check convertibility of arguments to parameters, even if the original expression is eventually deemed not expansion-iterable. A template instantiation might fail in a non-immediate context. A template instantiation can have non-local effects later observable via reflection.

The consideration whether the approach as presented, given its drawbacks, is preferable over other approaches with different drawbacks is an EWG design concern. CWG requests EWG to weigh in via paper issue #2615.

Date: 2026-01-23.22:56:25

Proposed resolution (approved by CWG 2026-01-23):

Change in 8.7 [stmt.expand] paragraph 3 as follows:

For an expression E, let the expressions begin-expr and end-expr be determined as specified in 8.6.5 [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 viable candidate (12.2.3 [over.match.viable]).
Date: 2025-11-11.00:00:00

(From submission #803.)

Subclause 8.7 [stmt.expand] paragraph 3 specifies:

For an expression E, let the expressions begin-expr and end-expr be determined as specified in 8.6.5 [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.

For the non-member case, this means any begin and end function will make an expression expansion-iterable. For example, a std::tuple is specified to be expansion-iterable, but it ought actually to be treated by destructuring.

Other appearances of "find at least one declaration" in the standard apply to member lookup only, e.g. in 7.6.2.4 [expr.await] bullet 3.2 or 9.7 [dcl.struct.bind] paragraph 7; the intent there is to "lock into" the member interpretation, giving a diagnostic if the begin or end member is not quite matching, e.g. due to missing const.

History
Date User Action Args
2026-01-23 22:56:25adminsetmessages: + msg8462
2026-01-23 22:56:25adminsetstatus: open -> review
2025-11-17 22:26:35adminsetmessages: + msg8389
2025-11-11 00:00:00admincreate