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) {
}
前面的代码片段在XCode中编译,但不在Visual Studio中编译(在使用'Bar': undeclared identifier
的第3行到最后一行失败)根据C ++标准,哪一个更正确。我假设clang以专有的非标准跟随方式推断Bar
的正确名称空间?
答案 0 :(得分:2)
Clang是正确的,因为标准中的一个模糊但有用的规则([basic.lookup.qual] / 3):
在 declarator-id 是 qualified-id 的声明中,声明 qualified-id 之前使用的名称 在定义的命名空间范围中查找;在范围内查找 qualified-id 后面的名称 成员的类或命名空间。
也就是说,只要编译器发现正在定义的实体FooFooClass::do_stuff
是类的成员,它就会在FooFooClass
范围内查找该声明中的所有后续名称。这意味着Bar
的查找首先要查找Foo::Foo::FooFooClass
的成员,然后是Foo::Foo
的成员,然后是Foo
的成员,然后是全局范围。由于在Bar
中找到Foo
,因此名称查找成功。