|
462 | 462 | \nontermdef{member-declaration}\br |
463 | 463 | \opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{member-declarator-list} \terminal{;}\br |
464 | 464 | function-definition\br |
| 465 | + friend-type-declaration\br |
465 | 466 | using-declaration\br |
466 | 467 | using-enum-declaration\br |
467 | 468 | static_assert-declaration\br |
|
504 | 505 | \terminal{=} \terminal{0} |
505 | 506 | \end{bnf} |
506 | 507 |
|
| 508 | +\begin{bnf} |
| 509 | +\nontermdef{friend-type-declaration}\br |
| 510 | + \keyword{friend} friend-type-specifier-list \terminal{;} |
| 511 | +\end{bnf} |
| 512 | + |
| 513 | +\begin{bnf} |
| 514 | +\nontermdef{friend-type-specifier-list}\br |
| 515 | + friend-type-specifier \opt{\terminal{...}}\br |
| 516 | + friend-type-specifier-list \terminal{,} friend-type-specifier \opt{\terminal{...}} |
| 517 | +\end{bnf} |
| 518 | + |
| 519 | +\begin{bnf} |
| 520 | +\nontermdef{friend-type-specifier}\br |
| 521 | + simple-type-specifier\br |
| 522 | + elaborated-type-specifier\br |
| 523 | + typename-specifier |
| 524 | +\end{bnf} |
| 525 | + |
507 | 526 | \pnum |
508 | 527 | In the absence of a \grammarterm{virt-specifier-seq}, |
509 | 528 | the token sequence \tcode{= 0} is treated as a \grammarterm{pure-specifier} |
|
623 | 642 | or if $P$ is in a complete-class context of \tcode{C}. |
624 | 643 | Otherwise, \tcode{C} is incomplete at $P$. |
625 | 644 |
|
| 645 | +\pnum |
| 646 | +If a \grammarterm{member-declaration} matches |
| 647 | +the syntactic requirements of \grammarterm{friend-type-declaration}, |
| 648 | +it is a \grammarterm{friend-type-declaration}. |
| 649 | + |
626 | 650 | \pnum |
627 | 651 | In a \grammarterm{member-declarator}, |
628 | 652 | an \tcode{=} immediately following the \grammarterm{declarator} |
|
4787 | 4811 |
|
4788 | 4812 | \pnum |
4789 | 4813 | A friend declaration that does not declare a function |
4790 | | -shall have one of the following forms: |
4791 | | - |
4792 | | -\begin{ncsimplebnf} |
4793 | | -\keyword{friend} elaborated-type-specifier \terminal{;}\br |
4794 | | -\keyword{friend} simple-type-specifier \terminal{;}\br |
4795 | | -\keyword{friend} typename-specifier \terminal{;} |
4796 | | -\end{ncsimplebnf} |
| 4814 | +shall be a \grammarterm{friend-type-declaration}. |
4797 | 4815 |
|
4798 | 4816 | \begin{note} |
4799 | 4817 | A friend declaration can be the |
4800 | 4818 | \grammarterm{declaration} in |
4801 | 4819 | a \grammarterm{template-declaration}\iref{temp.pre,temp.friend}. |
4802 | 4820 | \end{note} |
4803 | | -If the |
4804 | | -type specifier in a friend declaration designates a (possibly |
| 4821 | +If a \grammarterm{friend-type-specifier} in a friend declaration |
| 4822 | +designates a (possibly |
4805 | 4823 | cv-qualified) class type, that class is declared as a friend; otherwise, the |
4806 | | -friend declaration is ignored. |
| 4824 | +\grammarterm{friend-type-specifier} is ignored. |
4807 | 4825 | \begin{example} |
4808 | 4826 | \begin{codeblock} |
4809 | 4827 | class C; |
4810 | 4828 | typedef C Ct; |
| 4829 | +class E; |
4811 | 4830 |
|
4812 | 4831 | class X1 { |
4813 | 4832 | friend C; // OK, \tcode{class C} is a friend |
|
4819 | 4838 | friend class D; // OK, elaborated-type-specifier declares new class |
4820 | 4839 | }; |
4821 | 4840 |
|
4822 | | -template <typename T> class R { |
4823 | | - friend T; |
| 4841 | +template <typename ... Ts> class R { |
| 4842 | + friend Ts...; |
| 4843 | +}; |
| 4844 | + |
| 4845 | +template <class... Ts, class... Us> |
| 4846 | +class R<R<Ts...>, R<Us...>> { |
| 4847 | + friend Ts::Nested..., Us...; |
4824 | 4848 | }; |
4825 | 4849 |
|
4826 | 4850 | R<C> rc; // \tcode{class C} is a friend of \tcode{R<C>} |
4827 | | -R<int> Ri; // OK, \tcode{"friend int;"} is ignored |
| 4851 | +R<C, E> rce; // classes \tcode{C} and \tcode{E} are friends of \tcode{R<C, E>} |
| 4852 | +R<int> Ri; // OK, ``\tcode{friend int;}'' is ignored |
| 4853 | + |
| 4854 | +struct E { struct Nested; }; |
| 4855 | + |
| 4856 | +R<R<E>, R<C, int>> rr; // \tcode{E::Nested} and \tcode{C} are friends of \tcode{R<R<E>, R<C, int>>} |
4828 | 4857 | \end{codeblock} |
4829 | 4858 | \end{example} |
4830 | 4859 |
|
|
0 commit comments