[class.friend]

# 11 Classes [[class]](./#class)

## 11.8 Member access control [[class.access]](class.access#class.friend)

### 11.8.4 Friends [class.friend]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4916)

A friend of a class is a function or class that is
given permission to name the private and protected members of the class[.](#1.sentence-1)

A class specifies its friends, if any, by way of friend declarations[.](#1.sentence-2)

Such declarations give special access rights to the friends, but they
do not make the nominated friends members of the befriending class[.](#1.sentence-3)

[*Example [1](#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*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4946)

Declaring a class to be a friend implies that private and
protected members of the class granting friendship can be named in the[*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]")*s* and member declarations of the befriended
class[.](#2.sentence-1)

[*Example [2](#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 friendclass Y { A::B my; // OK, A​::​B accessible to nested member of friend};}; â *end example*]

[*Example [3](#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*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4984)

A friend declaration that does not declare a function
shall be a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1 General [class.mem.general]")[.](#3.sentence-1)

[*Note [1](#note-1)*:

A friend declaration can be the[*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") in
a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble"), [[temp.friend]](temp.friend "13.7.5 Friends"))[.](#3.sentence-2)

â *end note*]

If a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]") in a friend declaration
designates a (possibly
cv-qualified) class type, that class is declared as a friend; otherwise, the[*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]") is ignored[.](#3.sentence-3)

[*Example [4](#example-4)*: class C;typedef C Ct;class E;

class X1 {friend C; // OK, class C is a friend};

class X2 {friend Ct; // OK, class C is a friendfriend D; // error: D not foundfriend class D; // OK, elaborated-type-specifier declares new class};

template <typename ... Ts> class R {friend Ts...;};

template <class... Ts, class... Us>class R<R<Ts...>, R<Us...>> {friend Ts::Nested..., Us...;};

R<C> rc; // class C is a friend of R<C> R<C, E> rce; // classes C and E are friends of R<C, E> R<int> Ri; // OK, âfriend int;'' is ignoredstruct E { struct Nested; };

R<R<E>, R<C, int>> rr; // E​::​Nested and C are friends of R<R<E>, R<C, int>> â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5032)

[*Note [2](#note-2)*:

A friend declaration refers to an entity, not (all overloads of) a name[.](#4.sentence-1)

A member function of a classX can be a friend of
a classY[.](#4.sentence-2)

[*Example [5](#example-5)*: class Y {friend char* X::foo(int); friend X::X(char); // constructors can be friendsfriend X::~X(); // destructors can be friends}; â *end example*]

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5053)

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]](class.local "11.6 Local class declarations")) and the function name is unqualified[.](#5.sentence-1)

[*Example [6](#example-6)*: class M {friend void f() { } // definition of global f, a friend of M,// not the definition of a member function}; â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5066)

Such a function is implicitly an inline ([[dcl.inline]](dcl.inline "9.2.8 The inline specifier")) function
if it is attached to the global module[.](#6.sentence-1)

[*Note [3](#note-3)*:

If a friend function is defined outside a class,
it is not in the scope of the class[.](#6.sentence-2)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5074)

No[*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2 Storage class specifiers [dcl.stc]") shall appear in the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a friend declaration[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5081)

A member nominated by a friend declaration shall be accessible in the
class containing the friend declaration[.](#8.sentence-1)

The meaning of the friend declaration is the same whether the friend declaration
appears in the private, protected, or public ([[class.mem]](class.mem "11.4 Class members"))
portion of the class[*member-specification*](class.mem.general#nt:member-specification "11.4.1 General [class.mem.general]")[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5090)

Friendship is neither inherited nor transitive[.](#9.sentence-1)

[*Example [7](#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*]

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5118)

[*Note [4](#note-4)*:

A friend declaration never binds any names ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators"), [[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))[.](#10.sentence-1)

â *end note*]

[*Example [8](#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 friendclass Y {friend void g(); // A​::​g is a friendfriend void h(int); // A​::​h is a friend// ​::​h not consideredfriend 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​::​gvoid f(X) { /* ... */ } // definition of A​::​fvoid 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](#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 ​::​Xfriend class Y; // OKfriend class Z; // OK, introduces local class Zfriend void a(); // error, ​::​a is not consideredfriend void b(); // OKfriend void c(); // error};
 X* px; // OK, but ​::​X is found Z* pz; // error: no Z is found} â *end example*]
