This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


2635. Constrained structured bindings

Section: 9.1  [dcl.pre]     Status: C++23     Submitter: Corentin Jabot     Date: 2022-10-20

[Accepted as a DR at the November, 2022 meeting.]

Consider:

template<class T> concept C = true;
C auto [x, y] = std::pair{1, 2}; // ok?

Subclause 9.1 [dcl.pre] paragraph 6 specifies:

A simple-declaration with an identifier-list is called a structured binding declaration (9.6 [dcl.struct.bind]). If the decl-specifier-seq contains any decl-specifier other than static, thread_local, auto (9.2.9.7 [dcl.spec.auto]), or cv-qualifier s, the program is ill-formed.

Use of the word "contains" leads to an interpretation that any placeholder-type-specifier (9.2.9.7.1 [dcl.spec.auto.general]), possibly including a type-constraint, is valid here, since a placeholder-type-specifier is a decl-specifier and "contains" auto.

However, paper P1141R2 (Yet another approach for constrained declarations), applied in November 2018, expressly excludes structured bindings from constrained auto:

Structured bindings do deduce auto in some cases; however, the auto is deduced from the whole (and not from the individual components). It is somewhat doubtful that applying the constraint to the whole, as opposed to (for example) applying separately to each component, is the correct semantic. Therefore, we propose to defer enabling the application of constraints to structured bindings to separate papers.

Notwithstanding, clang, gcc, and MSVC accept the example.

Proposed resolution (approved by CWG 2022-10-21):

Change in 9.1 [dcl.pre] paragraph 6 specifies:

A simple-declaration with an identifier-list is called a structured binding declaration (9.6 [dcl.struct.bind]). If the decl-specifier-seq contains any decl-specifier other than static, thread_local, auto (9.2.9.7 [dcl.spec.auto]), or cv-qualifiers, the program is ill-formed. Each decl-specifier in the decl-specifier-seq shall be static, thread_local, auto (9.2.9.7 [dcl.spec.auto]), or a cv-qualifier. [ Example:
template<class T> concept C = true;
C auto [x, y] = std::pair{1, 2}; // error: constrained placeholder-type-specifier not permitted for structured bindings
-- end example ]