A
Andrey Tarasevich
Hello
Consider the following code fragment
namespace N {
struct S {
void foo();
};
}
using namespace N; // 1
class C {
friend struct S; // 2
C() {}
};
void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}
According to what I can see in the standard, friend declaration at point
2 is supposed to perform name lookup for unqualified name 'S' in order
to determine whether this is the first declaration of 'S'. According to
7.3.1.2/3, the lookup goes up to the innermost enclosing namespace scope
(which happens to be the global scope in this case). According to
3.4.1/2, name 'S' introduced by a using directive at point 1 is
considered to be a member of global namespace for the purposes of
unqualified name lookup. This makes me to conclude that the friend
declaration at 2 is supposed to refer to 'N::S' instead of introducing a
new [hidden] declaration of 'struct S' into the global namespace. I.e.
the constructor of 'C' is supposed to be accessible at point 3.
Experiments show that GCC 3.3.3 accepts the code. So does MSVC++ 2005
(for what it's worth). But Comeau Online rejects it, complaining that
the constructor is inaccessible at 3. I just found out that GCC 4.1 also
refuses to compile this code for the same reason.
Did something change in the language specification recently? Something
that applies in this case?
Consider the following code fragment
namespace N {
struct S {
void foo();
};
}
using namespace N; // 1
class C {
friend struct S; // 2
C() {}
};
void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}
According to what I can see in the standard, friend declaration at point
2 is supposed to perform name lookup for unqualified name 'S' in order
to determine whether this is the first declaration of 'S'. According to
7.3.1.2/3, the lookup goes up to the innermost enclosing namespace scope
(which happens to be the global scope in this case). According to
3.4.1/2, name 'S' introduced by a using directive at point 1 is
considered to be a member of global namespace for the purposes of
unqualified name lookup. This makes me to conclude that the friend
declaration at 2 is supposed to refer to 'N::S' instead of introducing a
new [hidden] declaration of 'struct S' into the global namespace. I.e.
the constructor of 'C' is supposed to be accessible at point 3.
Experiments show that GCC 3.3.3 accepts the code. So does MSVC++ 2005
(for what it's worth). But Comeau Online rejects it, complaining that
the constructor is inaccessible at 3. I just found out that GCC 4.1 also
refuses to compile this code for the same reason.
Did something change in the language specification recently? Something
that applies in this case?