|
49 | 49 | constraint-logical-and-expression \terminal{\&\&} primary-expression
|
50 | 50 | \end{bnf}
|
51 | 51 |
|
52 |
| -\begin{bnf} |
53 |
| -\nontermdef{type-constraint}\br |
54 |
| - \opt{nested-name-specifier} concept-name\br |
55 |
| - \opt{nested-name-specifier} concept-name \terminal{<} \opt{template-argument-list} \terminal{>} |
56 |
| -\end{bnf} |
57 |
| - |
58 | 52 | \begin{note}
|
59 | 53 | The \tcode{>} token following the
|
60 | 54 | \grammarterm{template-parameter-list} of a
|
|
141 | 135 | When such a declaration is used to declare a class template,
|
142 | 136 | no declarator is permitted.
|
143 | 137 |
|
144 |
| -\pnum |
145 |
| -A \grammarterm{type-constraint} \tcode{Q} that designates a concept \tcode{C} |
146 |
| -can be used to constrain a |
147 |
| -contextually-determined type or template type parameter pack \tcode{T} |
148 |
| -with a \grammarterm{constraint-expression} \tcode{E} defined as follows. |
149 |
| -If \tcode{Q} is of the form \tcode{C<A$_1$, $\cdots$, A$_n$>}, |
150 |
| -then let \tcode{E$'$} be \tcode{C<T, A$_1$, $\cdots$, A$_n$>}. |
151 |
| -Otherwise, let \tcode{E$'$} be \tcode{C<T>}. |
152 |
| -If \tcode{T} is not a pack, |
153 |
| -then \tcode{E} is \tcode{E$'$}, |
154 |
| -otherwise \tcode{E} is \tcode{(E$'$ \&\& ...)}. |
155 |
| -This \grammarterm{constraint-expression} \tcode{E} is called the |
156 |
| -\defnx{immediately-declared constraint}{constraint!immediately-declared} |
157 |
| -of \tcode{Q} for \tcode{T}. |
158 |
| -The concept designated by a \grammarterm{type-constraint} |
159 |
| -shall be a type concept\iref{temp.concept}. |
160 |
| - |
161 | 138 | \pnum
|
162 | 139 | \indextext{template name!linkage of}%
|
163 | 140 | A template name has linkage\iref{basic.link}.
|
|
267 | 244 | \keyword{typename}
|
268 | 245 | \end{bnf}
|
269 | 246 |
|
| 247 | +\begin{bnf} |
| 248 | +\nontermdef{type-constraint}\br |
| 249 | + \opt{nested-name-specifier} concept-name\br |
| 250 | + \opt{nested-name-specifier} concept-name \terminal{<} \opt{template-argument-list} \terminal{>} |
| 251 | +\end{bnf} |
| 252 | + |
270 | 253 | \begin{note}
|
271 | 254 | The \tcode{>} token following the
|
272 | 255 | \grammarterm{template-parameter-list} of a
|
|
353 | 336 | \end{codeblock}
|
354 | 337 | \end{note}
|
355 | 338 |
|
| 339 | +\pnum |
| 340 | +A \grammarterm{type-constraint} \tcode{Q} that designates a concept \tcode{C} |
| 341 | +can be used to constrain a |
| 342 | +contextually-determined type or template type parameter pack \tcode{T} |
| 343 | +with a \grammarterm{constraint-expression} \tcode{E} defined as follows. |
| 344 | +If \tcode{Q} is of the form \tcode{C<A$_1$, $\cdots$, A$_n$>}, |
| 345 | +then let \tcode{E$'$} be \tcode{C<T, A$_1$, $\cdots$, A$_n$>}. |
| 346 | +Otherwise, let \tcode{E$'$} be \tcode{C<T>}. |
| 347 | +If \tcode{T} is not a pack, |
| 348 | +then \tcode{E} is \tcode{E$'$}, |
| 349 | +otherwise \tcode{E} is \tcode{(E$'$ \&\& ...)}. |
| 350 | +This \grammarterm{constraint-expression} \tcode{E} is called the |
| 351 | +\defnx{immediately-declared constraint}{constraint!immediately-declared} |
| 352 | +of \tcode{Q} for \tcode{T}. |
| 353 | +The concept designated by a \grammarterm{type-constraint} |
| 354 | +shall be a type concept\iref{temp.concept}. |
| 355 | + |
| 356 | +\pnum |
| 357 | +A \grammarterm{type-parameter} that starts with a \grammarterm{type-constraint} |
| 358 | +introduces the immediately-declared constraint |
| 359 | +of the \grammarterm{type-constraint} for the parameter. |
| 360 | +\begin{example} |
| 361 | +\begin{codeblock} |
| 362 | +template<typename T> concept C1 = true; |
| 363 | +template<typename... Ts> concept C2 = true; |
| 364 | +template<typename T, typename U> concept C3 = true; |
| 365 | + |
| 366 | +template<C1 T> struct s1; // associates \tcode{C1<T>} |
| 367 | +template<C1... T> struct s2; // associates \tcode{(C1<T> \&\& ...)} |
| 368 | +template<C2... T> struct s3; // associates \tcode{(C2<T> \&\& ...)} |
| 369 | +template<C3<int> T> struct s4; // associates \tcode{C3<T, int>} |
| 370 | +template<C3<int>... T> struct s5; // associates \tcode{(C3<T, int> \&\& ...)} |
| 371 | +\end{codeblock} |
| 372 | +\end{example} |
| 373 | + |
356 | 374 | \pnum
|
357 | 375 | A non-type \grammarterm{template-parameter}
|
358 | 376 | shall have one of the following (optionally cv-qualified) types:
|
|
451 | 469 | \end{codeblock}
|
452 | 470 | \end{example}
|
453 | 471 |
|
454 |
| -\pnum |
455 |
| -A \grammarterm{type-parameter} that starts with a \grammarterm{type-constraint} |
456 |
| -introduces the immediately-declared constraint\iref{temp.pre} |
457 |
| -of the \grammarterm{type-constraint} for the parameter. |
458 |
| -\begin{example} |
459 |
| -\begin{codeblock} |
460 |
| -template<typename T> concept C1 = true; |
461 |
| -template<typename... Ts> concept C2 = true; |
462 |
| -template<typename T, typename U> concept C3 = true; |
463 |
| - |
464 |
| -template<C1 T> struct s1; // associates \tcode{C1<T>} |
465 |
| -template<C1... T> struct s2; // associates \tcode{(C1<T> \&\& ...)} |
466 |
| -template<C2... T> struct s3; // associates \tcode{(C2<T> \&\& ...)} |
467 |
| -template<C3<int> T> struct s4; // associates \tcode{C3<T, int>} |
468 |
| -template<C3<int>... T> struct s5; // associates \tcode{(C3<T, int> \&\& ...)} |
469 |
| -\end{codeblock} |
470 |
| -\end{example} |
471 |
| - |
472 | 472 | \pnum
|
473 | 473 | A non-type template parameter declared with a type that
|
474 | 474 | contains a placeholder type with a \grammarterm{type-constraint}
|
|
0 commit comments