diff --git a/source/declarations.tex b/source/declarations.tex index 21b62d4d1e..7656194e77 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -183,9 +183,11 @@ \pnum A \grammarterm{simple-declaration} with an \grammarterm{identifier-list} is called a \defn{structured binding declaration}\iref{dcl.struct.bind}. -The \grammarterm{decl-specifier-seq} shall -contain only the \grammarterm{type-specifier} \tcode{auto}\iref{dcl.spec.auto} -and \grammarterm{cv-qualifier}{s}. +If the \grammarterm{decl-specifier-seq} contains +any \grammarterm{decl-specifier} other than +\tcode{static}, \tcode{thread_local}, \tcode{auto}\iref{dcl.spec.auto}, or +\grammarterm{cv-qualifier}{s}, +the program is ill-formed. The \grammarterm{initializer} shall be of the form ``\tcode{=} \grammarterm{assignment-expression}'', of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'', @@ -370,8 +372,9 @@ The \tcode{thread_local} specifier indicates that the named entity has thread storage duration\iref{basic.stc.thread}. It shall be applied only -to the declaration of a variable of namespace -or block scope or to the declaration of a static data member. +to the declaration of a variable of namespace or block scope, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of a static data member. When \tcode{thread_local} is applied to a variable of block scope the \grammarterm{storage-class-specifier} \tcode{static} is implied if no other \grammarterm{storage-class-specifier} appears in the @@ -379,8 +382,11 @@ \pnum \indextext{restriction!\idxcode{static}}% -The \tcode{static} specifier shall be applied only to the declaration of a variable or -function or to the declaration of an anonymous union\iref{class.union.anon}. There can be no +The \tcode{static} specifier shall be applied only +to the declaration of a variable or function, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of an anonymous union\iref{class.union.anon}. +There can be no \tcode{static} function declarations within a block, nor any \tcode{static} function parameters. A \tcode{static} specifier used in the declaration of a variable declares the variable to have static storage @@ -6117,12 +6123,20 @@ of the \grammarterm{identifier-list} as names\iref{basic.scope.declarative} of \defn{structured binding}{s}. -Let \cv{} denote the -\grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq}. First, a -variable with a unique name \tcode{e} is introduced. If the +Let \cv{} denote the \grammarterm{cv-qualifier}{s} in +the \grammarterm{decl-specifier-seq} and +\placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of +the \grammarterm{decl-specifier-seq} (if any). +First, a variable with a unique name \tcode{e} is introduced. If the \grammarterm{assignment-expression} in the \grammarterm{initializer} -has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, \tcode{e} -has type \cv{}~\tcode{A} and each element is copy-initialized or direct-initialized +has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, +\tcode{e} is defined by + +\begin{ncbnf} +\opt{attribute-specifier-seq} \placeholder{S} \cv{} \terminal{A e ;} +\end{ncbnf} + +and each element is copy-initialized or direct-initialized from the corresponding element of the \grammarterm{assignment-expression} as specified by the form of the \grammarterm{initializer}. Otherwise, \tcode{e} @@ -6189,13 +6203,19 @@ Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. \end{note} In either case, \tcode{e} is an lvalue if the type of the entity \tcode{e} -is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ -designated by \tcode{std::tuple_element::type}, -variables are introduced with unique names $\tcode{r}_i$ -of type ``reference to $\tcode{T}_i$'' -initialized with the initializer~(\ref{dcl.init.ref}), -where the reference is an lvalue reference if the initializer is -an lvalue and an rvalue reference otherwise. +is an lvalue reference and an xvalue otherwise. +Given the type $\tcode{T}_i$ designated by +\tcode{std::tuple_element::type} and +the type $\tcode{U}_i$ designated by +either \tcode{$\tcode{T}_i$\&} or \tcode{$\tcode{T}_i$\&\&}, +where $\tcode{U}_i$ is an lvalue reference if +the initializer is an lvalue and an rvalue reference otherwise, +variables are introduced with unique names $\tcode{r}_i$ as follows: + +\begin{ncbnf} +\placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;} +\end{ncbnf} + Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ that refers to the object bound to $\tcode{r}_i$; the referenced type is $\tcode{T}_i$. diff --git a/source/expressions.tex b/source/expressions.tex index 0ead83cf27..9c98b8d332 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2164,9 +2164,7 @@ captured by a \grammarterm{lambda-expression} is odr-used\iref{basic.def.odr} in the scope containing the \grammarterm{lambda-expression}. If a \grammarterm{lambda-expression} -explicitly captures an entity that is not odr-usable -or -captures a structured binding (explicitly or implicitly), +explicitly captures an entity that is not odr-usable, the program is ill-formed. \begin{example} @@ -2298,7 +2296,8 @@ static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4); \end{codeblock} \end{example} -A bit-field or a member of an anonymous union shall not be captured by reference. +A bit-field, a structured binding, or a member of an anonymous union +shall not be captured by reference. \pnum An \grammarterm{id-expression} within