Skip to content

Commit aa8e85e

Browse files
authored
Merge 2018-06 CWG Motion 6
Fixes #2118
2 parents f5ebcca + e4f579e commit aa8e85e

File tree

6 files changed

+137
-74
lines changed

6 files changed

+137
-74
lines changed

source/declarations.tex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,12 @@
13711371
\tcode{decltype(e)} is the referenced type as given in
13721372
the specification of the structured binding declaration;
13731373

1374+
\item otherwise, if \tcode{e} is an unparenthesized \grammarterm{id-expression}
1375+
naming a non-type \grammarterm{template-parameter}\iref{temp.param},
1376+
\tcode{decltype(e)} is the type of the \grammarterm{template-parameter}
1377+
after performing any necessary type deduction
1378+
(\ref{dcl.spec.auto}, \ref{dcl.type.class.deduct});
1379+
13741380
\item otherwise, if \tcode{e} is an unparenthesized \grammarterm{id-expression} or
13751381
an unparenthesized
13761382
class
@@ -1876,9 +1882,11 @@
18761882
in the \grammarterm{type-specifier-seq}
18771883
in the \grammarterm{new-type-id} or \grammarterm{type-id}
18781884
of a \grammarterm{new-expression}\iref{expr.new},
1879-
or
18801885
as the \grammarterm{simple-type-specifier}
1881-
in an explicit type conversion (functional notation)\iref{expr.type.conv}.
1886+
in an explicit type conversion (functional notation)\iref{expr.type.conv},
1887+
or
1888+
as the \grammarterm{type-specifier} in the \grammarterm{parameter-declaration}
1889+
of a \grammarterm{template-parameter}\iref{temp.param}.
18821890
A placeholder for a deduced class type
18831891
shall not appear in any other context.
18841892

source/expressions.tex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,13 +712,17 @@
712712
If that \grammarterm{lambda-expression} is not declared \tcode{mutable},
713713
the type of such an identifier will typically be \tcode{const} qualified.
714714
\end{note}
715+
If the entity is a template parameter object for
716+
a template parameter of type \tcode{T}\iref{temp.param},
717+
the type of the expression is \tcode{const T}.
715718
Otherwise, the type of the expression is the type of the result.
716719
\begin{note}
717720
The type will be adjusted as described in \ref{expr.type}
718721
if it is cv-qualified or is a reference type.
719722
\end{note}
720723
The expression is an lvalue
721-
if the entity is a function, variable, or data member
724+
if the entity is a function, variable, data member, or
725+
template parameter object
722726
and a prvalue otherwise\iref{basic.lval};
723727
it is a bit-field if the identifier designates a bit-field\iref{dcl.struct.bind}.
724728
\begin{example}
@@ -5826,7 +5830,9 @@
58265830

58275831
\item
58285832
a non-volatile glvalue that refers to a non-volatile object
5829-
defined with \tcode{constexpr}, or that refers to a non-mutable subobject
5833+
defined with \tcode{constexpr} or
5834+
a template parameter object\iref{temp.param},
5835+
or that refers to a non-mutable subobject
58305836
of such an object, or
58315837

58325838
\item

source/lex.tex

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,17 +1785,17 @@
17851785
operator "" @\placeholder{X}@(@\placeholder{n}@ULL)
17861786
\end{codeblock}
17871787

1788-
Otherwise, \placeholder{S} shall contain a raw literal operator or a literal operator
1789-
template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator,
1788+
Otherwise, \placeholder{S} shall contain a raw literal operator
1789+
or a numeric literal operator template\iref{over.literal} but not both.
1790+
If \placeholder{S} contains a raw literal operator,
17901791
the literal \placeholder{L} is treated as a call of the form
17911792

17921793
\begin{codeblock}
17931794
operator "" @\placeholder{X}@(@"\placeholder{n}{"}@)
17941795
\end{codeblock}
17951796

1796-
Otherwise (\placeholder{S} contains a literal operator template), \placeholder{L} is treated as a call
1797-
of the form
1798-
1797+
Otherwise (\placeholder{S} contains a numeric literal operator template),
1798+
\placeholder{L} is treated as a call of the form
17991799

18001800
\begin{codeblock}
18011801
operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>()
@@ -1815,16 +1815,17 @@
18151815
operator "" @\placeholder{X}@(@\placeholder{f}@L)
18161816
\end{codeblock}
18171817

1818-
Otherwise, \placeholder{S} shall contain a raw literal operator or a literal operator
1819-
template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator,
1818+
Otherwise, \placeholder{S} shall contain a raw literal operator
1819+
or a numeric literal operator template\iref{over.literal} but not both.
1820+
If \placeholder{S} contains a raw literal operator,
18201821
the \grammarterm{literal} \placeholder{L} is treated as a call of the form
18211822

18221823
\begin{codeblock}
18231824
operator "" @\placeholder{X}@(@"\placeholder{f}{"}@)
18241825
\end{codeblock}
18251826

1826-
Otherwise (\placeholder{S} contains a literal operator template), \placeholder{L} is treated as a call
1827-
of the form
1827+
Otherwise (\placeholder{S} contains a numeric literal operator template),
1828+
\placeholder{L} is treated as a call of the form
18281829

18291830
\begin{codeblock}
18301831
operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>()
@@ -1835,12 +1836,20 @@
18351836
\end{note}
18361837

18371838
\pnum
1838-
If \placeholder{L} is a \grammarterm{user-defined-string-literal}, let \placeholder{str} be the
1839-
literal without its \grammarterm{ud-suffix} and let \placeholder{len} be
1840-
the number of
1841-
code units in \placeholder{str} (i.e., its length excluding the terminating
1842-
null character).
1843-
The literal \placeholder{L} is treated as a call of the form
1839+
If \placeholder{L} is a \grammarterm{user-defined-string-literal},
1840+
let \placeholder{str} be the literal without its \grammarterm{ud-suffix}
1841+
and let \placeholder{len} be the number of code units in \placeholder{str}
1842+
(i.e., its length excluding the terminating null character).
1843+
If \placeholder{S} contains a literal operator template with
1844+
a non-type template parameter for which \placeholder{str} is
1845+
a well-formed \grammarterm{template-argument},
1846+
the literal \placeholder{L} is treated as a call of the form
1847+
1848+
\begin{codeblock}
1849+
operator "" @\placeholder{X}@<@\placeholder{str}{}@>()
1850+
\end{codeblock}
1851+
1852+
Otherwise, the literal \placeholder{L} is treated as a call of the form
18441853

18451854
\begin{codeblock}
18461855
operator "" @\placeholder{X}@(@\placeholder{str}{}@, @\placeholder{len}{}@)

source/overloading.tex

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3543,11 +3543,19 @@
35433543
whose type is \tcode{const char*}.
35443544

35453545
\pnum
3546-
The declaration of a literal operator template shall have an empty
3547-
\grammarterm{parameter-declaration-clause} and its
3548-
\grammarterm{template-parameter-list} shall have a single
3549-
\grammarterm{template-parameter} that is a non-type template parameter
3550-
pack\iref{temp.variadic} with element type \tcode{char}.
3546+
A \defnx{numeric literal operator template}{literal!operator!template numeric}
3547+
is a literal operator template whose \grammarterm{template-parameter-list}
3548+
has a single \grammarterm{template-parameter}
3549+
that is a non-type template parameter pack\iref{temp.variadic}
3550+
with element type \tcode{char}.
3551+
A \defnx{string literal operator template}{literal!operator!template string}
3552+
is a literal operator template whose \grammarterm{template-parameter-list}
3553+
comprises
3554+
a single non-type \grammarterm{template-parameter} of class type.
3555+
The declaration of a literal operator template
3556+
shall have an empty \grammarterm{parameter-declaration-clause}
3557+
and shall declare either a numeric literal operator template
3558+
or a string literal operator template.
35513559

35523560
\pnum
35533561
Literal operators and literal operator templates shall not have C language linkage.

source/special.tex

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,22 @@
33263326
\item a friend of \tcode{C} having two parameters of type \tcode{const C\&}.
33273327
\end{itemize}
33283328

3329+
\pnum
3330+
\indextext{structural comparison operator|see{operator, structural comparison}}%
3331+
A three-way comparison operator for a class type \tcode{C}
3332+
is a \defnx{structural comparison operator}{operator!structural comparison}
3333+
if it is defined as defaulted in the definition of \tcode{C},
3334+
and all three-way comparison operators it invokes
3335+
are structural comparison operators.
3336+
\indextext{strong structural equality|see{equality, strong structural}}%
3337+
A type \tcode{T}
3338+
has \defnx{strong structural equality}{equality!strong structural}
3339+
if, for a glvalue \tcode{x} of type \tcode{const T},
3340+
\tcode{x <=> x} is a valid expression
3341+
of type \tcode{std::strong_ordering} or \tcode{std::strong_equality}
3342+
and either does not invoke a three-way comparison operator
3343+
or invokes a structural comparison operator.
3344+
33293345
\rSec2[class.spaceship]{Three-way comparison}
33303346
\indextext{operator!three-way comparison!defaulted}%
33313347

source/templates.tex

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -365,24 +365,21 @@
365365
\end{note}
366366

367367
\pnum
368-
A non-type
369-
\grammarterm{template-parameter}
370-
shall have one of the following (optionally
371-
cv-qualified)
372-
types:
368+
A non-type \grammarterm{template-parameter}
369+
shall have one of the following (optionally cv-qualified) types:
373370

374371
\begin{itemize}
375-
\item integral or enumeration type,
376-
377-
\item pointer to object or pointer to function,
372+
\item a type that is literal,
373+
has strong structural equality\iref{class.compare.default},
374+
has no \tcode{mutable} or \tcode{volatile} subobjects,
375+
and in which if there is a defaulted member \tcode{operator<=>},
376+
then it is declared public,
378377

379-
\item lvalue reference to object or lvalue reference to function,
378+
\item an lvalue reference type,
380379

381-
\item pointer to member,
380+
\item a type that contains a placeholder type\iref{dcl.spec.auto}, or
382381

383-
\item \tcode{std::nullptr_t}, or
384-
385-
\item a type that contains a placeholder type\iref{dcl.spec.auto}.
382+
\item a placeholder for a deduced class type\iref{dcl.type.class.deduct}.
386383
\end{itemize}
387384

388385
\pnum
@@ -398,27 +395,38 @@
398395
are ignored when determining its type.
399396

400397
\pnum
401-
A non-type non-reference
402-
\grammarterm{template-parameter}
403-
is a prvalue.
404-
It shall not be assigned to or in any other way have its value changed.
405-
A non-type non-reference
406-
\grammarterm{template-parameter}
407-
cannot have its address taken.
408-
When a non-type non-reference
409-
\grammarterm{template-parameter}
398+
When a non-type \grammarterm{template-parameter}
399+
of non-reference and non-class type
410400
is used as an initializer for a reference, a temporary is always used.
401+
An \grammarterm{id-expression} naming
402+
a non-type \grammarterm{template-parameter} of class type \tcode{T}
403+
denotes a static storage duration object of type \tcode{const T},
404+
known as a \defn{template parameter object},
405+
whose value is that of the corresponding template argument
406+
after it has been converted
407+
to the type of the \grammarterm{template-parameter}.
408+
All such template parameters in the program of the same type
409+
with the same value denote the same template parameter object.
410+
\begin{note}
411+
If an \grammarterm{id-expression} names
412+
a non-type non-reference \grammarterm{template-parameter},
413+
then it is a prvalue if it has non-class type.
414+
Otherwise, if it is of class type \tcode{T},
415+
it is an lvalue and has type \tcode{const T}\iref{expr.prim.id.unqual}.
416+
\end{note}
411417
\begin{example}
412418

413419
\begin{codeblock}
414-
template<const X& x, int i> void f() {
420+
struct A { auto operator<=>(A, A) = default; };
421+
template<const X& x, int i, A a> void f() {
415422
i++; // error: change of template-parameter value
416423

417424
&x; // OK
418425
&i; // error: address of non-reference template-parameter
419-
426+
&a; // OK
420427
int& ri = i; // error: non-const reference bound to temporary
421428
const int& cri = i; // OK: const reference bound to temporary
429+
const A& ra = a; // OK: const reference bound to a template parameter object
422430
}
423431
\end{codeblock}
424432
\end{example}
@@ -1284,27 +1292,28 @@
12841292
\rSec2[temp.arg.nontype]{Template non-type arguments}
12851293

12861294
\pnum
1287-
If the type of a \grammarterm{template-parameter}
1288-
contains a placeholder type~(\ref{dcl.spec.auto}, \ref{temp.param}),
1289-
the deduced parameter type is determined
1290-
from the type of the \grammarterm{template-argument}
1291-
by placeholder type deduction\iref{dcl.type.auto.deduct}.
1295+
If the type \tcode{T} of a \grammarterm{template-parameter}\iref{temp.param}
1296+
contains a placeholder type\iref{dcl.spec.auto}
1297+
or a placeholder for a deduced class type\iref{dcl.type.class.deduct},
1298+
the type of the parameter is the type deduced
1299+
for the variable \tcode{x} in the invented declaration
1300+
\begin{codeblock}
1301+
T x = @\grammarterm{template-argument}\itcorr[-1]@ ;
1302+
\end{codeblock}
12921303
If a deduced parameter type is not permitted
12931304
for a \grammarterm{template-parameter} declaration\iref{temp.param},
12941305
the program is ill-formed.
12951306

12961307
\pnum
1297-
A
1298-
\grammarterm{template-argument}
1299-
for a non-type
1300-
\grammarterm{template-parameter}
1301-
shall be
1302-
a converted
1303-
constant expression\iref{expr.const}
1308+
A \grammarterm{template-argument}
1309+
for a non-type \grammarterm{template-parameter}
1310+
shall be a converted constant expression\iref{expr.const}
13041311
of the type of the \grammarterm{template-parameter}.
13051312
For a non-type \grammarterm{template-parameter} of reference or pointer type,
1306-
the value of the constant expression shall not refer to
1307-
(or for a pointer type, shall not be the address of):
1313+
or for each non-static data member of reference or pointer type
1314+
in a non-type \grammarterm{template-parameter} of class type or subobject thereof,
1315+
the reference or pointer value shall not refer to
1316+
or be the address of (respectively):
13081317

13091318
\begin{itemize}
13101319
\item a subobject\iref{intro.object},
@@ -1353,20 +1362,27 @@
13531362

13541363
\pnum
13551364
\begin{note}
1356-
A string literal\iref{lex.string}
1357-
is not an acceptable
1358-
\grammarterm{template-argument}.
1365+
A string literal\iref{lex.string} is
1366+
not an acceptable \grammarterm{template-argument}
1367+
for a \grammarterm{template-parameter} of non-class type.
13591368
\begin{example}
13601369

13611370
\begin{codeblock}
1362-
template<class T, const char* p> class X {
1371+
template<class T, T p> class X {
13631372
@\commentellip@
13641373
};
13651374

1366-
X<int, "Studebaker"> x1; // error: string literal as template-argument
1375+
X<const char*, "Studebaker"> x; // error: string literal as template-argument
13671376

13681377
const char p[] = "Vivisectionist";
1369-
X<int,p> x2; // OK
1378+
X<const char*, p> y; // OK
1379+
1380+
class A {
1381+
constexpr A(const char*) {}
1382+
auto operator<=>(A, A) = default;
1383+
};
1384+
1385+
X<A, "Pyrophoricity"> z; // OK, string literal is a constructor argument to \tcode{A}
13701386
\end{codeblock}
13711387
\end{example}
13721388
\end{note}
@@ -2013,17 +2029,17 @@
20132029
refer to the same template and}
20142030
\item {their corresponding type \grammarterm{template-argument}{s} are the
20152031
same type and}
2016-
\item {their corresponding non-type
2017-
template arguments of
2018-
integral or enumeration type have identical values and}
2019-
\item {their corresponding non-type \grammarterm{template-argument}{s} of
2020-
pointer type refer to the same object or function or are both the null
2021-
pointer value and}
20222032
\item {their corresponding non-type \grammarterm{template-argument}{s} of
20232033
pointer-to-member type refer to the same class member or are both the null member
20242034
pointer value and}
20252035
\item {their corresponding non-type \grammarterm{template-argument}{s} of
20262036
reference type refer to the same object or function and}
2037+
\item {their remaining corresponding
2038+
non-type \grammarterm{template-argument}{s}
2039+
have the same type and value
2040+
after conversion to the type of the \grammarterm{template-parameter},
2041+
where they are considered to have the same value if they compare equal
2042+
with \tcode{operator<=>}, and}
20272043
\item {their corresponding template \grammarterm{template-argument}{s} refer
20282044
to the same template.}
20292045
\end{itemize}

0 commit comments

Comments
 (0)