|
367 | 367 | A non-type \grammarterm{template-parameter}
|
368 | 368 | shall have one of the following (optionally cv-qualified) types:
|
369 | 369 | \begin{itemize}
|
370 |
| -\item a literal type that |
371 |
| - has strong structural equality\iref{class.compare.default}, |
372 |
| - |
373 |
| -\item an lvalue reference type, |
374 |
| - |
| 370 | +\item a structural type (see below), |
375 | 371 | \item a type that contains a placeholder type\iref{dcl.spec.auto}, or
|
376 |
| - |
377 | 372 | \item a placeholder for a deduced class type\iref{dcl.type.class.deduct}.
|
378 | 373 | \end{itemize}
|
379 |
| - |
380 |
| -\pnum |
381 |
| -\begin{note} |
382 |
| -Other types are disallowed either explicitly below or implicitly by |
383 |
| -the rules governing the form of |
384 |
| -\grammarterm{template-argument}{s}\iref{temp.arg}. |
385 |
| -\end{note} |
386 | 374 | The top-level
|
387 | 375 | \grammarterm{cv-qualifier}{s}
|
388 | 376 | on the
|
389 | 377 | \grammarterm{template-parameter}
|
390 | 378 | are ignored when determining its type.
|
391 | 379 |
|
| 380 | +\pnum |
| 381 | +A \defnadj{structural}{type} is one of the following: |
| 382 | +\begin{itemize} |
| 383 | +\item a scalar type, or |
| 384 | +\item an lvalue reference type, or |
| 385 | +\item a literal class type with the following properties: |
| 386 | +\begin{itemize} |
| 387 | +\item |
| 388 | +all base classes and non-static data members are public and non-mutable and |
| 389 | +\item |
| 390 | +the types of all bases classes and non-static data members are |
| 391 | +structural types or (possibly multi-dimensional) array thereof. |
| 392 | +\end{itemize} |
| 393 | +\end{itemize} |
| 394 | + |
392 | 395 | \pnum
|
393 | 396 | An \grammarterm{id-expression} naming
|
394 | 397 | a non-type \grammarterm{template-parameter} of class type \tcode{T}
|
|
399 | 402 | to the type of the \grammarterm{template-parameter}.
|
400 | 403 | All such template parameters in the program of the same type
|
401 | 404 | with the same value denote the same template parameter object.
|
| 405 | +A template parameter object shall have constant destruction\iref{expr.const}. |
402 | 406 | \begin{note}
|
403 | 407 | If an \grammarterm{id-expression} names
|
404 | 408 | a non-type non-reference \grammarterm{template-parameter},
|
|
409 | 413 | \begin{example}
|
410 | 414 | \begin{codeblock}
|
411 | 415 | using X = int;
|
412 |
| -struct A { friend bool operator==(const A&, const A&) = default; }; |
| 416 | +struct A {}; |
413 | 417 | template<const X& x, int i, A a> void f() {
|
414 |
| - i++; // error: change of template-parameter value |
| 418 | + i++; // error: change of \grammarterm{template-parameter} value |
415 | 419 |
|
416 | 420 | &x; // OK
|
417 | 421 | &i; // error: address of non-reference template-parameter
|
|
424 | 428 | \end{example}
|
425 | 429 |
|
426 | 430 | \pnum
|
| 431 | +\begin{note} |
427 | 432 | A non-type
|
428 | 433 | \grammarterm{template-parameter}
|
429 |
| -shall not be declared to have floating-point or void type. |
| 434 | +cannot be declared to have type \cv{} \tcode{void}. |
430 | 435 | \begin{example}
|
431 | 436 | \begin{codeblock}
|
432 |
| -template<double d> class X; // error |
433 |
| -template<double* pd> class Y; // OK |
434 |
| -template<double& rd> class Z; // OK |
| 437 | +template<void v> class X; // error |
| 438 | +template<void* pv> class Y; // OK |
435 | 439 | \end{codeblock}
|
436 | 440 | \end{example}
|
| 441 | +\end{note} |
437 | 442 |
|
438 | 443 | \pnum
|
439 | 444 | A non-type
|
|
1184 | 1189 | for a non-type \grammarterm{template-parameter}
|
1185 | 1190 | shall be a converted constant expression\iref{expr.const}
|
1186 | 1191 | of the type of the \grammarterm{template-parameter}.
|
| 1192 | +\begin{note} |
| 1193 | +If the \grammarterm{template-argument} |
| 1194 | +represents a set of overloaded functions |
| 1195 | +(or a pointer or member pointer to such), |
| 1196 | +the matching function is selected from the set\iref{over.over}. |
| 1197 | +\end{note} |
| 1198 | + |
| 1199 | +\pnum |
1187 | 1200 | For a non-type \grammarterm{template-parameter} of reference or pointer type,
|
1188 | 1201 | or for each non-static data member of reference or pointer type
|
1189 | 1202 | in a non-type \grammarterm{template-parameter} of class type or subobject thereof,
|
1190 | 1203 | the reference or pointer value shall not refer to
|
1191 | 1204 | or be the address of (respectively):
|
1192 | 1205 | \begin{itemize}
|
1193 |
| -\item a subobject\iref{intro.object}, |
1194 | 1206 | \item a temporary object\iref{class.temporary},
|
1195 | 1207 | \item a string literal\iref{lex.string},
|
1196 |
| -\item the result of a \tcode{typeid} expression\iref{expr.typeid}, or |
1197 |
| -\item a predefined \mname{func} variable\iref{dcl.fct.def.general}. |
| 1208 | +\item the result of a \tcode{typeid} expression\iref{expr.typeid}, |
| 1209 | +\item a predefined \mname{func} variable\iref{dcl.fct.def.general}, or |
| 1210 | +\item a subobject\iref{intro.object} of one of the above. |
1198 | 1211 | \end{itemize}
|
1199 | 1212 |
|
1200 |
| -\begin{note} |
1201 |
| -If the \grammarterm{template-argument} |
1202 |
| -represents a set of overloaded functions |
1203 |
| -(or a pointer or member pointer to such), |
1204 |
| -the matching function is selected from the set\iref{over.over}. |
1205 |
| -\end{note} |
1206 |
| - |
1207 | 1213 | \pnum
|
1208 | 1214 | \begin{example}
|
1209 | 1215 | \begin{codeblock}
|
|
1228 | 1234 | A<&f> a; // selects \tcode{f(int)}
|
1229 | 1235 |
|
1230 | 1236 | template<auto n> struct B { @\commentellip@ };
|
1231 |
| -B<5> b1; // OK: template parameter type is \tcode{int} |
1232 |
| -B<'a'> b2; // OK: template parameter type is \tcode{char} |
1233 |
| -B<2.5> b3; // error: template parameter type cannot be \tcode{double} |
| 1237 | +B<5> b1; // OK, template parameter type is \tcode{int} |
| 1238 | +B<'a'> b2; // OK, template parameter type is \tcode{char} |
| 1239 | +B<2.5> b3; // OK, template parameter type is \tcode{double} |
| 1240 | +B<void(0)> b4; // error: template parameter type cannot be \tcode{void} |
1234 | 1241 | \end{codeblock}
|
1235 | 1242 | \end{example}
|
1236 | 1243 |
|
|
1245 | 1252 | @\commentellip@
|
1246 | 1253 | };
|
1247 | 1254 |
|
1248 |
| -X<const char*, "Studebaker"> x; // error: string literal as template-argument |
| 1255 | +X<const char*, "Studebaker"> x; // error: string literal as \grammarterm{template-argument} |
| 1256 | +X<const char*, "Knope" + 1> x2; // error: subobject of string literal as \grammarterm{template-argument} |
1249 | 1257 |
|
1250 | 1258 | const char p[] = "Vivisectionist";
|
1251 | 1259 | X<const char*, p> y; // OK
|
1252 | 1260 |
|
1253 | 1261 | struct A {
|
1254 | 1262 | constexpr A(const char*) {}
|
1255 |
| - friend bool operator==(const A&, const A&) = default; |
1256 | 1263 | };
|
1257 | 1264 |
|
1258 | 1265 | X<A, "Pyrophoricity"> z; // OK, string literal is a constructor argument to \tcode{A}
|
1259 | 1266 | \end{codeblock}
|
1260 | 1267 | \end{example}
|
1261 | 1268 | \end{note}
|
1262 | 1269 |
|
1263 |
| -\pnum |
1264 |
| -\begin{note} |
1265 |
| -The address of an array element or non-static data member is not an acceptable |
1266 |
| -\grammarterm{template-argument}. |
1267 |
| -\begin{example} |
1268 |
| -\begin{codeblock} |
1269 |
| -template<int* p> class X { }; |
1270 |
| - |
1271 |
| -int a[10]; |
1272 |
| -struct S { int m; static int s; } s; |
1273 |
| - |
1274 |
| -X<&a[2]> x3; // error: address of array element |
1275 |
| -X<&s.m> x4; // error: address of non-static member |
1276 |
| -X<&s.s> x5; // OK: address of static member |
1277 |
| -X<&S::s> x6; // OK: address of static member |
1278 |
| -\end{codeblock} |
1279 |
| -\end{example} |
1280 |
| -\end{note} |
1281 |
| - |
1282 | 1270 | \pnum
|
1283 | 1271 | \begin{note}
|
1284 | 1272 | A temporary object
|
|
1291 | 1279 | \begin{codeblock}
|
1292 | 1280 | template<const int& CRI> struct B { @\commentellip@ };
|
1293 | 1281 |
|
1294 |
| -B<1> b2; // error: temporary would be required for template argument |
| 1282 | +B<1> b1; // error: temporary would be required for template argument |
1295 | 1283 |
|
1296 | 1284 | int c = 1;
|
1297 |
| -B<c> b1; // OK |
| 1285 | +B<c> b2; // OK |
| 1286 | + |
| 1287 | +struct X { int n; }; |
| 1288 | +struct Y { const int &r; }; |
| 1289 | +template<Y y> struct C { @\commentellip@ }; |
| 1290 | +C<Y{X{1}.n}> c; // error: subobject of temporary object used to initialize |
| 1291 | + // reference member of template parameter |
1298 | 1292 | \end{codeblock}
|
1299 | 1293 | \end{example}
|
1300 | 1294 | \end{note}
|
|
1939 | 1933 | Two \grammarterm{template-id}{s} refer to the same
|
1940 | 1934 | class, function, or variable if
|
1941 | 1935 | \begin{itemize}
|
1942 |
| -\item {their \grammarterm{template-name}{s}, |
1943 |
| -\grammarterm{operator-function-id}{s}, or \grammarterm{literal-operator-id}{s} |
1944 |
| -refer to the same template and} |
1945 |
| -\item {their corresponding type \grammarterm{template-argument}{s} are the |
1946 |
| -same type and} |
1947 |
| -\item {their corresponding non-type \grammarterm{template-argument}{s} of |
1948 |
| -pointer-to-member type refer to the same class member or are both the null member |
1949 |
| -pointer value and} |
1950 |
| -\item {their corresponding non-type \grammarterm{template-argument}{s} of |
1951 |
| -reference type refer to the same object or function and} |
1952 |
| -\item {their remaining corresponding |
1953 |
| -non-type \grammarterm{template-argument}{s} |
1954 |
| -have the same type and value |
1955 |
| -after conversion to the type of the \grammarterm{template-parameter}, |
1956 |
| -where they are considered to have the same value if they compare equal |
1957 |
| -with the \tcode{==} operator\iref{expr.eq}, and} |
1958 |
| -\item {their corresponding template \grammarterm{template-argument}{s} refer |
1959 |
| -to the same template.} |
| 1936 | +\item |
| 1937 | +their \grammarterm{template-name}{s}, |
| 1938 | +\grammarterm{operator-function-id}{s}, or |
| 1939 | +\grammarterm{literal-operator-id}{s} |
| 1940 | +refer to the same template, and |
| 1941 | + |
| 1942 | +\item |
| 1943 | +their corresponding type \grammarterm{template-argument}{s} |
| 1944 | +are the same type, and |
| 1945 | + |
| 1946 | +\item |
| 1947 | +their corresponding non-type \grammarterm{template-argument}{s} |
| 1948 | +are template-argument-equivalent (see below) |
| 1949 | +after conversion to the type of the \grammarterm{template-parameter}, and |
| 1950 | + |
| 1951 | +\item |
| 1952 | +their corresponding template \grammarterm{template-argument}{s} |
| 1953 | +refer to the same template. |
| 1954 | +\end{itemize} |
| 1955 | + |
| 1956 | +\pnum |
| 1957 | +Two values are \defn{template-argument-equivalent} if |
| 1958 | +they are of the same type and |
| 1959 | +\begin{itemize} |
| 1960 | +\item |
| 1961 | +they are of integral type and their values are the same, or |
| 1962 | + |
| 1963 | +\item |
| 1964 | +they are of floating-point type and their values are identical, or |
| 1965 | + |
| 1966 | +\item |
| 1967 | +they are of type \tcode{std::nullptr_t}, or |
| 1968 | + |
| 1969 | +\item |
| 1970 | +they are of enumeration type and their values are the same,% |
| 1971 | +\footnote{The identity of enumerators is not preserved.} or |
| 1972 | + |
| 1973 | +\item |
| 1974 | +they are of pointer type and they have the same pointer value, or |
| 1975 | + |
| 1976 | +\item |
| 1977 | +they are of pointer-to-member type and they refer to the same class member |
| 1978 | +or are both the null member pointer value, or |
| 1979 | + |
| 1980 | +\item |
| 1981 | +they are of reference type and they refer to the same object or function, or |
| 1982 | + |
| 1983 | +\item |
| 1984 | +they are of array type and their corresponding elements are template-argument-equivalent,% |
| 1985 | +\footnote{An array as a \grammarterm{template-parameter} decays to a pointer.} or |
| 1986 | + |
| 1987 | +\item |
| 1988 | +they are of union type and either |
| 1989 | +they both have no active member or |
| 1990 | +they have the same active member and their active members are template-argument-equivalent, or |
| 1991 | + |
| 1992 | +\item |
| 1993 | +they are of class type and |
| 1994 | +their corresponding direct subobjects and reference members are template-argument-equivalent. |
1960 | 1995 | \end{itemize}
|
| 1996 | + |
| 1997 | +\pnum |
1961 | 1998 | \begin{example}
|
1962 | 1999 | \begin{codeblock}
|
1963 | 2000 | template<class E, int size> class buffer { @\commentellip@ };
|
|
0 commit comments