Nach clang, gcc und vs2013, ist die Funktion Outer::f
nicht ein Freund der Klasse Outer::Inner
.Die Elementfunktion Outer :: f() ist kein Freund der Klasse Outer :: Inner. Warum?
struct Outer {
void f() {}
class Inner {
friend void f();
static const int i = 0;
};
};
void f() { int i = Outer::Inner::i; }
Von [namespace.memdef]/3 I die Funktion Outer::f
ein Freund von Outer::Inner
, statt ::f
, zu sein, weil der Freund Erklärung in seinem Namespace nicht die ersten ist erwarten würde den Namen f
enthält.
[Namespace, memdef]/3 (Schwerpunkt liegt mir):
Jeder Name zuerst in einem Namespace deklariert ist ein Mitglied dieser Namespace. Wenn ein Freund Erklärung in einer nicht-lokalen Klasse erste eine Klasse deklariert, Funktion, Klasse-Vorlage oder Funktion Vorlage der Freund ist ein Mitglied der innersten umschließenden Namespace. Die Friend-Deklaration selbst macht den Namen nicht sichtbar für unqualifiziertes Nachschlagen (3.4.1) oder qualifiziertes Nachschlagen (3.4.3). [Hinweis: Der Name des Freundes wird in seinem Namespace sichtbar, wenn eine übereinstimmende Deklaration im Namespacebereich bereitgestellt wird (entweder vor oder nach der Klassendefinition, die Freundschaft gewährt). - Endnote] Wenn eine Freundes- oder Funktionsvorlage aufgerufen wird, kann der Name durch den Namen lookup gefunden werden, der Funktionen aus Namespaces und Klassen berücksichtigt, die den Typen der Funktion Argumente (3.4.2) zugeordnet sind. Wenn der Name in einer Friend-Deklaration weder qualifiziert ist noch eine Template-ID und die Deklaration eine Funktion oder ein elaborated-type-specifier ist, darf die Suche zur Bestimmung, ob die Entität zuvor deklariert wurde, keine Bereiche außerhalb der Innerster einschließender Namespace.
Der zitierte Text sagt "... das Nachschlagen, um zu bestimmen, ob die Entität zuvor deklariert wurde, darf keine Bereiche ** außerhalb ** des innersten einschließenden Namespace berücksichtigen". Die Frage ist hier, was "draußen" eigentlich gemein ist? Soll es auch mit "außer" oder "neben" sein (in diesem Fall bedeutet die obige Passage, dass die Suche im innersten Namespace und * nirgendwo sonst *) durchgeführt wird? Aber in diesem Fall, wenn ich mich nicht irre, sollte es "außerhalb von" sagen ... Oder soll sich "draußen" auf größere umhüllende Namespaces beziehen, die den innersten umschließen? – AnT
Im letzteren Fall eliminiert "outside" nicht "struct Outer" von der Suche. – AnT
Ich gehe davon aus, dass die Suche im innersten Namespace und nirgendwo sonst für die im Satz erklärten Fälle ausgeführt wird: 'Wenn der Name in einer Friend-Deklaration weder qualifiziert noch eine Template-ID ist und die Deklaration eine Funktion oder ein elaborierter Typ ist -specifier, darf die Suche zur Bestimmung, ob die Entität zuvor deklariert wurde, keine Bereiche außerhalb des innersten umschließenden Namespace berücksichtigen. Dabei ist der innerste einschließende Namespace in diesem Fall der globale Namespace. – Belloc