Skip to content

P0960r3 Allow initializing aggregates from a parenthesized list of va… #2743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3925,6 +3925,12 @@
\item A temporary object bound to a reference parameter in a function call\iref{expr.call}
persists until the completion of the full-expression containing the call.

\item A temporary object bound to a reference element of
an aggregate of class type initialized from
a parenthesized \grammarterm{expression-list}\iref{dcl.init}
persists until the completion of the full-expression
containing the \grammarterm{expression-list}.

\item The lifetime of a temporary bound to the returned value in a function \tcode{return} statement\iref{stmt.return} is not extended; the temporary is destroyed at the end of the full-expression in the \tcode{return} statement.

\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}.
Expand Down
74 changes: 69 additions & 5 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4370,7 +4370,23 @@
and the initializer is a string literal, see~\ref{dcl.init.string}.
\item If the initializer is \tcode{()}, the object is value-initialized.
\item
Otherwise, if the destination type is an array, the program is ill-formed.
Otherwise, if the destination type is an array,
the object is initialized as follows.
Let $x_1$, $\dotsc$, $x_k$ be
the elements of the \grammarterm{expression-list}.
If the destination type is an array of unknown bound,
it is defined as having $k$ elements.
Let $n$ denote the array size after this potential adjustment.
If $k$ is greater than $n$,
the program is ill-formed.
Otherwise, the $i^\text{th}$ array element is copy-initialized with
$x_i$ for each $1 \leq i \leq k$, and
value-initialized for each $k < i \leq n$.
For each $1 \leq i < j \leq n$,
every value computation and side effect associated with
the initialization of the $i^\text{th}$ element of the array
is sequenced before those associated with
the initialization of the $j^\text{th}$ element.
\item
If the destination type is a (possibly cv-qualified) class type:

Expand All @@ -4390,12 +4406,60 @@
constructors are considered.
The applicable constructors
are enumerated\iref{over.match.ctor}, and the best one is chosen
through overload resolution\iref{over.match}.
The constructor so selected
through overload resolution\iref{over.match}. Then:
\begin{itemize}
\item
If overload resolution is successful,
the selected constructor
is called to initialize the object, with the initializer
expression or \grammarterm{expression-list} as its argument(s).
If no constructor applies, or the overload resolution is
ambiguous, the initialization is ill-formed.
\item
Otherwise, if no constructor is viable,
the destination type is
a (possibly cv-qualified) aggregate class \tcode{A}, and
the initializer is a parenthesized \grammarterm{expression-list},
the object is initialized as follows.
Let $e_1$, $\dotsc$, $e_n$ be the elements of the aggregate\iref{dcl.init.aggr}.
Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}.
If $k$ is greater than $n$, the program is ill-formed.
The element $e_i$ is copy-initialized with
$x_i$ for $1 \leq i \leq k$.
The remaining elements are initialized with
their default member initializers, if any, and
otherwise are value-initialized.
For each $1 \leq i < j \leq n$,
every value computation and side effect
associated with the initialization of $e_i$
is sequenced before those associated with the initialization of $e_j$.
\begin{note}
By contrast with direct-list-initialization,
narrowing conversions\iref{dcl.init.list} are permitted,
designators are not permitted,
a temporary object bound to a reference
does not have its lifetime extended\iref{class.temporary}, and
there is no brace elision.
\begin{example}
\begin{codeblock}
struct A {
int a;
int&& r;
};

int f();
int n = 10;

A a1{1, f()}; // OK, lifetime is extended
A a2(1, f()); // well-formed, but dangling reference
A a3{1.0, 1}; // error: narrowing conversion
A a4(1.0, 1); // well-formed, but dangling reference
A a5(1.0, std::move(n)); // OK
\end{codeblock}
\end{example}
\end{note}
\item
Otherwise, the initialization is ill-formed.
\end{itemize}

\item
Otherwise (i.e., for the remaining copy-initialization cases),
user-defined conversions that can convert from the
Expand Down
1 change: 1 addition & 0 deletions source/preprocessor.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,7 @@
\endhead
\defnxname{cpp_aggregate_bases} & \tcode{201603L} \\ \rowsep
\defnxname{cpp_aggregate_nsdmi} & \tcode{201304L} \\ \rowsep
\defnxname{cpp_aggregate_paren_init} & \tcode{201902L} \\ \rowsep
\defnxname{cpp_alias_templates} & \tcode{200704L} \\ \rowsep
\defnxname{cpp_aligned_new} & \tcode{201606L} \\ \rowsep
\defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep
Expand Down