------- Additional Comments From lerdsuwa at gcc dot gnu dot org 2005-01-13 14:52 ------- > So B's ctor uses the global A without the friend declaration and with the > friend declaration the local injected A? Sometimes the holy standard confuses > me a bit.
No. With or without friend declaration, the B's ctor should always pick the global A. This is one weird rule in C++ standard. The idea is that name lookup for 'friend struct A;' only find A within one level outside the classes enclosing the friend declaration: namespace N { class A { class B { friend class C; // Classes A and B enclosing this friend. // one level up is namespace N. // Since there is no B::C nor A::C, // this refers to N::C }; }; } void f() { class D { friend class E; // Since there is no D::E, one level up // is the local class E inside function f. }; } When refer to A without the prefix 'class' or 'struct', any name can be used. However the name introduced by friend must be explicitly declared first to be visible. Now it's your example, expanded with more cases and comment describing the way it should be handled. struct A {}; namespace Boo { struct B { friend struct A; // Since there is no B::A, this means Boo::A // It introduces Boo::A but still invisible // since there is no Boo::A declaration prior // to this friend. B(const A&) {}; // Boo::A is still not visible, // so ::A is chosen here }; void f(const A&) {} // Boo::A is still not visible, choose ::A struct A; // Declare Boo::A explicitly, so Boo::A is now visible void g(const A&) {} // Choose Boo::A } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19403