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': 未声明的标识符
),根据 C++ 标准,该代码片段更为正确。我假设 clang 正在以专有的非标准遵循方式推断 Bar
的正确命名空间?
最佳答案
Clang 是正确的,因为标准中存在一个晦涩但有用的规则 ([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.
也就是说,一旦编译器发现所定义的实体 FooFooClass::do_stuff
是类的成员,它就会在该声明的范围内查找所有以下名称FooFooClass
。这意味着 Bar
的查找首先查找 Foo::Foo::FooFooClass
的成员,然后查找 Foo::Foo
的成员,然后是 Foo 的成员,然后是全局范围。由于在 Foo
中找到了 Bar
,因此名称查找成功。
关于c++ - Xcode 推断命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42658852/