Es gibt einen solchen Code:
#include <iostream>
class A{
public:
friend void fun(A a){std::cout << "Im here" << std::endl;}
friend void fun2(){ std::cout << "Im here2" << std::endl; }
friend void fun3();
};
void fun3(){
std::cout << "Im here3" << std::endl;
}
int main()
{
fun(A()); // works ok
//fun2(); error: 'fun2' was not declared in this scope
//A::fun2(); error: 'fun2' is not a member of 'A'
fun3(); // works ok
}
Wie greife ich auf die Funktion fun2() zu?
class A{
public:
friend void fun(A a){std::cout << "Im here" << std::endl;}
friend void fun2(){ std::cout << "Im here2" << std::endl; }
friend void fun3();
};
Obwohl Ihre Definition von fun2
tut Definieren Sie eine “globale” Funktion anstelle eines Members und machen Sie sie zu einer friend
von A
Gleichzeitig fehlt Ihnen immer noch eine Deklaration derselben Funktion im globalen Geltungsbereich selbst.
Das bedeutet, dass kein Code in diesem Bereich eine Ahnung davon hat fun2
existiert.
Das gleiche Problem tritt z fun
außer dass die argumentabhängige Suche die Funktion übernehmen und finden kann, da ein Argument vom Typ vorhanden ist A
.
Ich empfehle stattdessen, Ihre Funktionen auf die übliche Weise zu definieren:
class A {
friend void fun(A a);
friend void fun2();
friend void fun3();
};
void fun(A a) { std::cout << "I'm here" << std::endl; }
void fun2() { std::cout << "I'm here2" << std::endl; }
void fun3();
Beachten Sie das jetzt alles funktioniert (außer fun3
weil ich es nie definiert habe).

CB Bailey
Der Grund, warum Sie anrufen können fun
ist das die Friend-Deklaration innerhalb der Klasse A
macht es nur über argumentabhängige Suche sichtbar. Andernfalls machen Friend-Deklarationen die Funktionen, die sie deklarieren, nicht automatisch außerhalb des Klassenbereichs sichtbar, in dem sie erscheinen.
Sie müssen eine Deklaration im Namespace-Bereich oder innerhalb hinzufügen main
zu machen fun2
sichtbar darin main
.
Z.B
void fun2();
fun3
ist innen sichtbar main
weil ihre Definition (außerhalb der Klasse) auch eine Deklaration ist, die sie sichtbar macht main
.
ISO/IEC 14882:2011 7.3.1.2:
Der Name des Freundes wird nicht durch unqualifiziertes Nachschlagen (3.4.1) oder durch qualifiziertes Nachschlagen (3.4.3) gefunden, bis eine übereinstimmende Deklaration in diesem Namensraumbereich bereitgestellt wird (entweder vor oder nach der Klassendefinition, die Freundschaft gewährt).
3.4.2 (Argumentabhängige Namenssuche) / 4:
Alle Friend-Funktionen im Namensraumbereich oder Friend-Funktionsvorlagen, die in zugeordneten Klassen deklariert sind, sind in ihren jeweiligen Namensräumen sichtbar, selbst wenn sie während einer gewöhnlichen Suche (11.3) nicht sichtbar sind.
9157800cookie-checkGreifen Sie auf die in der Klasse definierte Freundesfunktion zuyes
+1: Gut formulierte Frage.
– Leichtigkeitsrennen im Orbit
16. Oktober 2011 um 17:26 Uhr
Wir sehen diese Art von Code im intelligenten Zeiger von boost: intrusive_ptr, was mich zunächst verwirrte, was das sein sollte. Für mich macht es keinen Sinn, es so zu definieren, sondern irgendwo im Bereich einen Freund zu definieren und einen Prototyp in der Klassenbereichsdeklaration als Freund zu markieren, was besser lesbar ist!
– Gabriel
14. Juni 2014 um 14:59 Uhr