11 Classes [class]

11.8 Member access control [class.access]

11.8.4 Friends [class.friend]

A friend of a class is a function or class that is given permission to name the private and protected members of the class.
A class specifies its friends, if any, by way of friend declarations.
Such declarations give special access rights to the friends, but they do not make the nominated friends members of the befriending class.
[Example 1:
The following example illustrates the differences between members and friends: class X { int a; friend void friend_set(X*, int); public: void member_set(int); }; void friend_set(X* p, int i) { p->a = i; } void X::member_set(int i) { a = i; } void f() { X obj; friend_set(&obj,10); obj.member_set(10); }
— end example]
Declaring a class to be a friend implies that private and protected members of the class granting friendship can be named in the base-specifiers and member declarations of the befriended class.
[Example 2: class A { class B { }; friend class X; }; struct X : A::B { // OK: A​::​B accessible to friend A::B mx; // OK: A​::​B accessible to member of friend class Y { A::B my; // OK: A​::​B accessible to nested member of friend }; }; — end example]
[Example 3: class X { enum { a=100 }; friend class Y; }; class Y { int v[X::a]; // OK, Y is a friend of X }; class Z { int v[X::a]; // error: X​::​a is private }; — end example]
A friend declaration that does not declare a function shall have one of the following forms:
[Note 1:
A friend declaration can be the declaration in a template-declaration ([temp.pre], [temp.friend]).
— end note]
If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the friend declaration is ignored.
[Example 4: class C; typedef C Ct; class X1 { friend C; // OK: class C is a friend }; class X2 { friend Ct; // OK: class C is a friend friend D; // error: D not found friend class D; // OK: elaborated-type-specifier declares new class }; template <typename T> class R { friend T; }; R<C> rc; // class C is a friend of R<C> R<int> Ri; // OK: "friend int;" is ignored — end example]
A function first declared in a friend declaration has the linkage of the namespace of which it is a member ([basic.link]).
Otherwise, the function retains its previous linkage ([dcl.stc]).
[Note 2:
A friend declaration refers to an entity, not (all overloads of) a name.
A member function of a class X can be a friend of a class Y.
[Example 5: class Y { friend char* X::foo(int); friend X::X(char); // constructors can be friends friend X::~X(); // destructors can be friends }; — end example]
— end note]
A function may be defined in a friend declaration of a class if and only if the class is a non-local class ([class.local]) and the function name is unqualified.
[Example 6: class M { friend void f() { } // definition of global f, a friend of M, // not the definition of a member function }; — end example]
Such a function is implicitly an inline ([dcl.inline]) function if it is attached to the global module.
[Note 3:
If a friend function is defined outside a class, it is not in the scope of the class.
— end note]
No storage-class-specifier shall appear in the decl-specifier-seq of a friend declaration.
A member nominated by a friend declaration shall be accessible in the class containing the friend declaration.
The meaning of the friend declaration is the same whether the friend declaration appears in the private, protected, or public ([class.mem]) portion of the class member-specification.
Friendship is neither inherited nor transitive.
[Example 7: class A { friend class B; int a; }; class B { friend class C; }; class C { void f(A* p) { p->a++; // error: C is not a friend of A despite being a friend of a friend } }; class D : public B { void f(A* p) { p->a++; // error: D is not a friend of A despite being derived from a friend } }; — end example]
[Note 4:
A friend declaration never binds any names ([dcl.meaning], [dcl.type.elab]).
— end note]
[Example 8: // Assume f and g have not yet been declared. void h(int); template <class T> void f2(T); namespace A { class X { friend void f(X); // A​::​f(X) is a friend class Y { friend void g(); // A​::​g is a friend friend void h(int); // A​::​h is a friend // ​::​h not considered friend void f2<>(int); // ​::​f2<>(int) is a friend }; }; // A​::​f, A​::​g and A​::​h are not visible here X x; void g() { f(x); } // definition of A​::​g void f(X) { /* ... */ } // definition of A​::​f void h(int) { /* ... */ } // definition of A​::​h // A​::​f, A​::​g and A​::​h are visible here and known to be friends } using A::x; void h() { A::f(x); A::X::f(x); // error: f is not a member of A​::​X A::X::Y::g(); // error: g is not a member of A​::​X​::​Y } — end example]
[Example 9: class X; void a(); void f() { class Y; extern void b(); class A { friend class X; // OK, but X is a local class, not ​::​X friend class Y; // OK friend class Z; // OK, introduces local class Z friend void a(); // error, ​::​a is not considered friend void b(); // OK friend void c(); // error }; X* px; // OK, but ​::​X is found Z* pz; // error: no Z is found } — end example]