Skip to content

Commit 2f4245e

Browse files
committed
P2893R3 Variadic friends
1 parent 9ec133c commit 2f4245e

File tree

4 files changed

+62
-17
lines changed

4 files changed

+62
-17
lines changed

source/classes.tex

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@
461461
\nontermdef{member-declaration}\br
462462
\opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{member-declarator-list} \terminal{;}\br
463463
function-definition\br
464+
friend-type-declaration\br
464465
using-declaration\br
465466
using-enum-declaration\br
466467
static_assert-declaration\br
@@ -503,6 +504,24 @@
503504
\terminal{=} \terminal{0}
504505
\end{bnf}
505506

507+
\begin{bnf}
508+
\nontermdef{friend-type-declaration}\br
509+
\keyword{friend} friend-type-specifier-list \terminal{;}
510+
\end{bnf}
511+
512+
\begin{bnf}
513+
\nontermdef{friend-type-specifier-list}\br
514+
friend-type-specifier \opt{\terminal{...}}\br
515+
friend-type-specifier-list \terminal{,} friend-type-specifier \opt{\terminal{...}}
516+
\end{bnf}
517+
518+
\begin{bnf}
519+
\nontermdef{friend-type-specifier}\br
520+
simple-type-specifier\br
521+
elaborated-type-specifier\br
522+
typename-specifier
523+
\end{bnf}
524+
506525
\pnum
507526
\indextext{definition!class}%
508527
The \grammarterm{member-specification} in a class definition declares the
@@ -610,6 +629,11 @@
610629
or if $P$ is in a complete-class context of \tcode{C}.
611630
Otherwise, \tcode{C} is incomplete at $P$.
612631

632+
\pnum
633+
If a \grammarterm{member-declaration} matches
634+
the syntactic requirements of \grammarterm{friend-type-declaration},
635+
it is a \grammarterm{friend-type-declaration}.
636+
613637
\pnum
614638
In a \grammarterm{member-declarator},
615639
an \tcode{=} immediately following the \grammarterm{declarator}
@@ -4841,7 +4865,7 @@
48414865

48424866
\pnum
48434867
A friend declaration that does not declare a function
4844-
shall have one of the following forms:
4868+
shall be a \grammarterm{friend-type-declaration}.
48454869

48464870
\begin{ncsimplebnf}
48474871
\keyword{friend} elaborated-type-specifier \terminal{;}\br
@@ -4854,14 +4878,15 @@
48544878
\grammarterm{declaration} in
48554879
a \grammarterm{template-declaration}\iref{temp.pre,temp.friend}.
48564880
\end{note}
4857-
If the
4858-
type specifier in a friend declaration designates a (possibly
4881+
If a \grammarterm{friend-type-specifier} in a friend declaration
4882+
designates a (possibly
48594883
cv-qualified) class type, that class is declared as a friend; otherwise, the
4860-
friend declaration is ignored.
4884+
\grammarterm{friend-type-specifier} is ignored.
48614885
\begin{example}
48624886
\begin{codeblock}
48634887
class C;
48644888
typedef C Ct;
4889+
class E;
48654890

48664891
class X1 {
48674892
friend C; // OK, \tcode{class C} is a friend
@@ -4873,12 +4898,22 @@
48734898
friend class D; // OK, elaborated-type-specifier declares new class
48744899
};
48754900

4876-
template <typename T> class R {
4877-
friend T;
4901+
template <typename ... Ts> class R {
4902+
friend Ts...;
4903+
};
4904+
4905+
template <class... Ts, class... Us>
4906+
class R<R<Ts...>, R<Us...>> {
4907+
friend Ts::Nested..., Us...;
48784908
};
48794909

48804910
R<C> rc; // \tcode{class C} is a friend of \tcode{R<C>}
4911+
R<C, E> rce; // classes \tcode{C} and \tcode{E} are friends of \tcode{R<C, E>}
48814912
R<int> Ri; // OK, \tcode{"friend int;"} is ignored
4913+
4914+
struct E { struct Nested; };
4915+
4916+
R<R<E>, R<C, int>> rr; // \tcode{E::Nested} and \tcode{C} are friends of \tcode{R<R<E>, R<C, int>>}
48824917
\end{codeblock}
48834918
\end{example}
48844919

source/declarations.tex

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
block-declaration\br
2929
nodeclspec-function-declaration\br
3030
function-definition\br
31+
friend-type-declaration\br
3132
template-declaration\br
3233
deduction-guide\br
3334
linkage-specification\br
@@ -117,6 +118,11 @@
117118
the declaration that are \emph{not} nested within scopes nested within
118119
the declaration.
119120

121+
\pnum
122+
If a \grammarterm{name-declaration} matches
123+
the syntactic requirements of \grammarterm{friend-type-declaration},
124+
it is a \grammarterm{friend-type-declaration}.
125+
120126
\pnum
121127
A
122128
\grammarterm{simple-declaration} or
@@ -1520,13 +1526,13 @@
15201526
The target scope of $E$ is the nearest enclosing namespace or block scope.
15211527

15221528
\pnum
1523-
If an \grammarterm{elaborated-type-specifier} appears with
1524-
the \keyword{friend} specifier as an entire \grammarterm{member-declaration},
1525-
the \grammarterm{member-declaration} shall have one of the following forms:
1529+
A \grammarterm{friend-type-specifier}
1530+
that is an \grammarterm{elaborated-type-specifier}
1531+
shall have one of the following forms:
15261532
\begin{ncsimplebnf}
1527-
\keyword{friend} class-key \opt{nested-name-specifier} identifier \terminal{;}\br
1528-
\keyword{friend} class-key simple-template-id \terminal{;}\br
1529-
\keyword{friend} class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{;}
1533+
class-key \opt{nested-name-specifier} identifier\br
1534+
class-key simple-template-id\br
1535+
class-key nested-name-specifier \opt{\keyword{template}} simple-template-id
15301536
\end{ncsimplebnf}
15311537
Any unqualified lookup for the \grammarterm{identifier} (in the first case)
15321538
does not consider scopes that contain the target scope; no name is bound.

source/preprocessor.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,7 @@
18691869
\defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep
18701870
\defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep
18711871
\defnxname{cpp_using_enum} & \tcode{201907L} \\ \rowsep
1872+
\defnxname{cpp_variable_friend} & \tcode{202403L} \\ \rowsep
18721873
\defnxname{cpp_variable_templates} & \tcode{201304L} \\ \rowsep
18731874
\defnxname{cpp_variadic_templates} & \tcode{200704L} \\ \rowsep
18741875
\defnxname{cpp_variadic_using} & \tcode{201611L} \\

source/templates.tex

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@
5959
\end{note}
6060

6161
\pnum
62-
The
63-
\grammarterm{declaration}
64-
in a
65-
\grammarterm{template-declaration}
66-
(if any)
62+
The \grammarterm{declaration} in a \grammarterm{template-declaration} (if any)
6763
shall
6864
\begin{itemize}
6965
\item declare or define a function, a class, or a variable, or
@@ -73,6 +69,8 @@
7369

7470
\item define a member template of a class or class template, or
7571

72+
\item be a \grammarterm{friend-type-declaration}, or
73+
7674
\item be a \grammarterm{deduction-guide}, or
7775

7876
\item be an \grammarterm{alias-declaration}.
@@ -2739,6 +2737,9 @@
27392737
\item In a \grammarterm{using-declaration}\iref{namespace.udecl};
27402738
the pattern is a \grammarterm{using-declarator}.
27412739

2740+
\item In a \grammarterm{friend-type-declaration}\iref{class.mem.general};
2741+
the pattern is a \grammarterm{friend-type-specifier}.
2742+
27422743
\item In a template parameter pack that is a pack expansion\iref{temp.param}:
27432744
\begin{itemize}
27442745
\item
@@ -4408,6 +4409,8 @@
44084409
\grammarterm{elaborated-type-specifier},
44094410
\grammarterm{class-or-decltype}, or
44104411
\item
4412+
a \grammarterm{simple-type-specifier} of a \grammarterm{friend-type-specifier}, or
4413+
\item
44114414
a \grammarterm{type-specifier} of a
44124415
\begin{itemize}
44134416
\item \grammarterm{new-type-id},

0 commit comments

Comments
 (0)