2017-03-07 43 views
2
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)哪一个更正确根据C++标准。我假设clang是以专有的非标准跟踪方式推断Bar的正确命名空间?Xcode推断命名空间?

+0

GCC 7.0.1也有它的工作,所以它可能是MSVC的错。 – user975989

回答

2

铛是正确的,由于在标准的晦涩但有用的规则([basic.lookup.qual]/3):

在声明,其中说明符-ID合格代码,在合格代码被声明为 之前使用的名称在定义的命名空间范围中查找;在成员的类或名称空间的范围 中查找限定标识后面的名称。

也就是说,只要编译器看到的是,实体被定义,FooFooClass::do_stuff,是一个类的成员,它看起来了所有下列名称中的FooFooClass范围了上述声明。这意味着查找Bar首先查找Foo::Foo::FooFooClass的成员,然后是Foo::Foo的成员,然后是Foo的成员,然后是全局范围。由于在Foo中找到Bar,所以名称查找成功。