friend, template und namespaces
-
Hallo,
folgendes Problem beschäftigt mich: Ich möchte eine function template zum friend einer Klasse N::A machen:
// forward declare A namespace N { class A; } // forward declare x template<typename T> void x(T, N::A& a); // declare A namespace N { class A { private: int id; template<typename T> friend void ::x(T, A&); }; } // define x template<typename T> void x(T, N::A& a) { a.id = 20; } // use int main() { N::A a; ::x(0l, a); }Dies funktioniert aber mit gcc nicht.
test.cc: In function ‘void x(T, N::A&) [with T = long int]’: test.cc:36: instantiated from here test.cc:17: error: ‘int N::A::id’ is private test.cc:28: error: within this contextWenn ich x aber in ein Namespace M übersiedle, und Zeile 20 wie folgt ändere, dann funktionierts:
friend void M::x(T, A&);Hat irgendwer einen Tipp wie ich das hinkriegen könnte das x im globalem Namespace bleibt?
danke
Peter
-
Hi, dein Problem ist folgendes:
Erstens deklarierst du eine Funktion x hier:
// forward declare x template<typename T> void x(T, N::A& a);Danach auch wieder hier:
template<typename T> friend void ::x(T, A&);Würdest du hier:
N::A a; ::x(0l, a);Das :: vor x weglassen, würdest du merken das dies Mehrdeutig ist.
Das kommt durch den "Koenig-Lookups", der besagt falls man ein Argument N::A an eine Funktion übergibt, dass auch in N nach der Funktion geschaut wird, zudem gibt es auch nochmal die globale Funktion x;Lösung des Problems:
-> // forward declare x weg
-> template<typename T> friend void x(T, A&); // also ohne ::
-> und bei der Def von x wieder N::x { definiton }Edit: Also so:
namespace N { class A; } // declare A namespace N { class A { private: int id; public: template<typename T> friend void x(T, A&); }; } // define x template<typename T> void N::x(T, N::A& a) { a.id = 20; } // use int main() { N::A a; x(0l, a); }
-
Hallo KasF,
danke für die Antwort, es compiliert! Was mich allerdings wundert, ist wieso ich
in mainx(0l, a);aufrufen kann, wenn doch x im namespace N liegt:
template<typename T> void N::x(T, N::A& a) { ...Oder verstehe ich da was falsch?
Peter
-
ubu_roi schrieb:
x(0l, a);Wie schon erwähnt, hat das mit dem "Koenig Lookup" zu tun. Da dein Argument a vom Typ N::A ist, wird auch in N nach einer Funktion x gesucht.
Näheres dazu hier: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Koenig#Answ