Skip to content

Commit 9f7f23c

Browse files
committed
P2686R5 constexpr structured bindings and references to constexpr variables
- Merge the change to [temp.arg.nontype] with existing text.
1 parent 219b959 commit 9f7f23c

File tree

4 files changed

+309
-82
lines changed

4 files changed

+309
-82
lines changed

source/basic.tex

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -441,24 +441,59 @@
441441
A variable is named by an expression
442442
if the expression is an \grammarterm{id-expression} that denotes it.
443443
A variable \tcode{x} that is named by a
444-
potentially-evaluated expression $E$
445-
is \defnx{odr-used}{odr-use} by $E$ unless
444+
potentially-evaluated expression $N$
445+
that appears at a point $P$
446+
is \defnx{odr-used}{odr-use} by $N$ unless
446447
\begin{itemize}
447448
\item
448-
\tcode{x} is a reference that is
449-
usable in constant expressions\iref{expr.const}, or
449+
\tcode{x} is a reference
450+
that is usable in constant expressions at $P$\iref{expr.const} or
450451
\item
451-
\tcode{x} is a variable of non-reference type that is
452-
usable in constant expressions and has no mutable subobjects, and
453-
$E$ is an element of the set of potential results of an expression
454-
of non-volatile-qualified non-class type
455-
to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or
452+
$N$ is an element of the set of potential results of an expression $E$, where
453+
\begin{itemize}
454+
\item
455+
$E$ is a discarded-value expression\iref{expr.context}
456+
to which the lvalue-to-rvalue conversion is not applied or
457+
\item
458+
\tcode{x} is a non-volatile object
459+
that is usable in constant expressions at $P$ and
460+
has no mutable subobjects and
461+
\begin{itemize}
462+
\item
463+
$E$ is a class member access expression\iref{expr.ref}
464+
naming a non-static data member of reference type and
465+
whose object expression has non-volatile-qualified type or
456466
\item
457-
\tcode{x} is a variable of non-reference type, and
458-
$E$ is an element of the set of potential results
459-
of a discarded-value expression\iref{expr.context}
460-
to which the lvalue-to-rvalue conversion is not applied.
467+
the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and
468+
$E$ has non-volatile-qualified non-class type
461469
\end{itemize}
470+
\end{itemize}
471+
\end{itemize}
472+
\begin{example}
473+
\begin{codeblock}
474+
int f(int);
475+
int g(int&);
476+
struct A {
477+
int x;
478+
};
479+
struct B {
480+
int& r;
481+
};
482+
int h(bool cond) {
483+
constexpr A a = {1};
484+
constexpr const volatile A& r = a; // odr-uses \tcode{a}
485+
int _ = f(cond ? a.x : r.x); // does not odr-use \tcode{a} or \tcode{r}
486+
int x, y;
487+
constexpr B b1 = {x}, b2 = {y}; // odr-uses \tcode{x} and \tcode{y}
488+
int _ = g(cond ? b1.r : b2.r); // does not odr-use \tcode{b1} or \tcode{b2}
489+
int _ = ((cond ? x : y), 0); // does not odr-use \tcode{x} or \tcode{y}
490+
return [] {
491+
return b1.r; // error: \tcode{b1} is odr-used here because the object
492+
// referred to by \tcode{b1.r} is not constexpr-referenceable here
493+
}();
494+
}
495+
\end{codeblock}
496+
\end{example}
462497

463498
\pnum
464499
A structured binding is odr-used if it appears as a potentially-evaluated expression.
@@ -6886,7 +6921,7 @@
68866921
\pnum
68876922
\indextext{initialization!constant}%
68886923
\defnx{Constant initialization}{constant initialization} is performed
6889-
if a variable or temporary object with static or thread storage duration
6924+
if a variable with static or thread storage duration
68906925
is constant-initialized\iref{expr.const}.
68916926
\indextext{initialization!zero-initialization}%
68926927
If constant initialization is not performed, a variable with static

source/declarations.tex

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@
213213
a \defn{structured binding declaration}\iref{dcl.struct.bind}.
214214
Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq}
215215
shall be
216+
\tcode{constexpr},
217+
\tcode{constinit},
216218
\tcode{static},
217219
\tcode{thread_local},
218220
\tcode{auto}\iref{dcl.spec.auto}, or
@@ -850,7 +852,8 @@
850852

851853
\pnum
852854
The \keyword{constexpr} specifier shall be applied only to
853-
the definition of a variable or variable template or
855+
the definition of a variable or variable template,
856+
a structured binding declaration, or
854857
the declaration of a function or function template.
855858
The \keyword{consteval} specifier shall be applied only to
856859
the declaration of a function or function template.
@@ -995,9 +998,7 @@
995998
Such an object
996999
shall have literal type and
9971000
shall be initialized.
998-
In any \keyword{constexpr} variable declaration,
999-
the full-expression of the initialization
1000-
shall be a constant expression\iref{expr.const}.
1001+
A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const}.
10011002
A \keyword{constexpr} variable that is an object,
10021003
as well as any temporary to which a \keyword{constexpr} reference is bound,
10031004
shall have constant destruction.
@@ -1008,6 +1009,16 @@
10081009
};
10091010
constexpr pixel ur = { 1294, 1024 }; // OK
10101011
constexpr pixel origin; // error: initializer missing
1012+
1013+
namespace N {
1014+
void f() {
1015+
int x;
1016+
constexpr int& ar = x; // OK
1017+
static constexpr int& sr = x; // error: \tcode{x} is not constexpr-representable
1018+
// at the point indicated below
1019+
}
1020+
// immediate scope here is that of \tcode{N}
1021+
}
10111022
\end{codeblock}
10121023
\end{example}
10131024

@@ -1016,7 +1027,12 @@
10161027

10171028
\pnum
10181029
The \keyword{constinit} specifier shall be applied only
1019-
to a declaration of a variable with static or thread storage duration.
1030+
to a declaration of a variable with static or thread storage duration
1031+
or to a structured binding declaration\iref{dcl.struct.bind}.
1032+
\begin{note}
1033+
A structured binding declaration introduces a uniquely named variable,
1034+
to which the \tcode{constinit} specifier applies.
1035+
\end{note}
10201036
If the specifier is applied to any declaration of a variable,
10211037
it shall be applied to the initializing declaration.
10221038
No diagnostic is required if no \keyword{constinit} declaration
@@ -7030,8 +7046,10 @@
70307046
appertains to the structured binding so introduced.
70317047
Let \cv{} denote the \grammarterm{cv-qualifier}{s} in
70327048
the \grammarterm{decl-specifier-seq} and
7033-
\placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of
7034-
the \grammarterm{decl-specifier-seq} (if any).
7049+
\placeholder{S} consist of
7050+
each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq}
7051+
that is \tcode{constexpr}, \tcode{constinit}, or
7052+
a \grammarterm{storage-class-specifier}.
70357053
A \cv{} that includes \tcode{volatile} is deprecated;
70367054
see~\ref{depr.volatile.type}.
70377055
First, a variable with a unique name \exposid{e} is introduced. If the

0 commit comments

Comments
 (0)