Reputation: 1093
namespace Foo {
class Bar { };
}
namespace Foo {
namespace Foo {
class FooFooClass {
public:
void do_stuff(Bar& key);
};
}
}
using namespace Foo::Foo;
void FooFooClass::do_stuff(Bar& key) {
}
The preceding snippet compiles in XCode, but does not compile in Visual Studio (fails on 3rd to last line with 'Bar': undeclared identifier
) which one is more correct according to the C++ Standard. I'm assuming that clang is inferring the correct namespace for Bar
in a proprietary non-standard-following way?
Upvotes: 2
Views: 323
Reputation: 119457
Clang is correct, due to an obscure but useful rule in the standard ([basic.lookup.qual]/3):
In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member’s class or namespace.
That is, as soon as the compiler sees that the entity being defined, FooFooClass::do_stuff
, is a member of a class, it looks up all following names in that declaration in the scope of FooFooClass
. That means lookup of Bar
starts by looking for a member of Foo::Foo::FooFooClass
, then a member of Foo::Foo
, then a member of Foo
, then the global scope. Since Bar
is found in Foo
, the name lookup succeeds.
Upvotes: 2