From 25499386ef636bed408a27b3802ffe3eaad3e69b Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Mon, 15 Jun 2026 23:00:33 +0100 Subject: [PATCH 1/2] P3847R1 (Lexical order for lambdas) --- source/expressions.tex | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 72f77d87bb..f7c62011e2 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2986,11 +2986,10 @@ \tcode{\&} \opt{\tcode{...}} \grammarterm{identifier} \grammarterm{initializer}. \end{itemize} For each entity captured by copy, an -unnamed non-static data member is declared in the closure type. The declaration order of -these members is unspecified. The type of such a data member is -the referenced type if the entity is a reference to an object, -an lvalue reference to the referenced function type if the entity is a reference to a function, or -the type of the corresponding captured entity otherwise. +unnamed non-static data member is declared in the closure type. +The type of such a data member is the referenced type if the entity is a reference to an object, +an lvalue reference to the referenced function type if the entity is a reference to a function, +or the type of the corresponding captured entity otherwise. A member of an anonymous union shall not be captured by copy. \pnum @@ -3091,18 +3090,34 @@ \end{codeblock} \end{example} +\pnum +The non-static data members in the closure type are declared in an unspecified order, +except that the members introduced for explicit captures are declared in an order +consistent with that of those captures. + \pnum The entities that are captured by copy are used to direct-initialize each corresponding non-static data member -of the resulting closure object, and the non-static data members corresponding to the -\grammarterm{init-capture}{s} are initialized as indicated by the corresponding -\grammarterm{initializer} (which may be copy- or direct-initialization). (For array members, the array elements are -direct-initialized in increasing subscript order.) These initializations are performed -when the \grammarterm{lambda-expression} is evaluated and -in the (unspecified) order in which the non-static data members are declared. +of the resulting closure object. The non-static data members corresponding to the +\grammarterm{init-capture}{s} and the (reference) variables declared by \grammarterm{init-capture}{s} +without corresponding non-static data members are initialized as indicated by the corresponding +\grammarterm{initializer} (which may be copy- or direct-initialization). +(For array members, the array elements are direct-initialized in increasing subscript order.) +These initializations are performed when the \grammarterm{lambda-expression} is evaluated, +in an order consistent with the (unspecified) order in which the non-static data members are declared +and with the order of explicit captures. \begin{note} This ensures that the destructions will occur in the reverse order of the constructions. \end{note} +\begin{example} +\begin{codeblock} +void f(std::vector &&v) { + [size = v.size(), + own = std::move(v)] {}; +} +\end{codeblock} +Since \tcode{size} is initialized before \tcode{own}, it contains the original size of \tcode{v}. +\end{example} \pnum \begin{note} From ed09d213385895c92792c5f876464f29d2240091 Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Sun, 21 Jun 2026 13:13:28 +0100 Subject: [PATCH 2/2] fixup: apply feedback --- source/expressions.tex | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index f7c62011e2..4c49eb308d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3098,10 +3098,11 @@ \pnum The entities that are captured by copy are used to direct-initialize each corresponding non-static data member -of the resulting closure object. The non-static data members corresponding to the +of the resulting closure object. +The non-static data members corresponding to the \grammarterm{init-capture}{s} and the (reference) variables declared by \grammarterm{init-capture}{s} -without corresponding non-static data members are initialized as indicated by the corresponding -\grammarterm{initializer} (which may be copy- or direct-initialization). +without corresponding non-static data members are initialized as indicated by the +corresponding \grammarterm{initializer} (which may be copy- or direct-initialization). (For array members, the array elements are direct-initialized in increasing subscript order.) These initializations are performed when the \grammarterm{lambda-expression} is evaluated, in an order consistent with the (unspecified) order in which the non-static data members are declared @@ -3116,7 +3117,8 @@ own = std::move(v)] {}; } \end{codeblock} -Since \tcode{size} is initialized before \tcode{own}, it contains the original size of \tcode{v}. +Since \tcode{size} is initialized before \tcode{own}, +it contains the original size of \tcode{v}. \end{example} \pnum