|
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