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}