nri*_*lin 14 c++ namespaces using-directives language-lawyer c++11
有时候我会找到类似下面的代码(实际上有些类向导会创建这样的代码):
// C.h
namespace NS {
class C {
void f();
};
}
Run Code Online (Sandbox Code Playgroud)
并在实现文件中:
// C.cpp
#include "C.h"
using namespace NS;
void C::f() {
//...
}
Run Code Online (Sandbox Code Playgroud)
我试过的所有编译器都接受那种代码(gcc,clang,msvc,compileonline.com).是什么让我感到不舒服的是using namespace NS;.从我的观点来看,C::f()生活在全局命名空间中的环境中,该环境对生活在命名空间NS中的对象具有不合格的访问权限.但是在编译器的观点中void C::f()存在namespace NS.正如我尝试的所有编译器都分享了这一观点,他们可能是正确的,但是标准中的这个意见得到了支持?
Tem*_*Rex 15
是的,语法确实合法,但不,你的函数确实存在于命名空间NS中.您看到的代码实际上等同于
namespace NS { void C::f() { /* ... } }
Run Code Online (Sandbox Code Playgroud)
或者
void NS::C::f() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
这可能比你习惯的更类似.
由于using指令,您不仅可以在调用代码时省略NS部分,还可以在其定义中省略NS部分.标准有一个与您的代码匹配的示例(在粗体强调部分之后):
3.4.3.2命名空间成员[namespace.qual]
7在声明命名空间成员的声明中,声明者成员是qualified-id,假定命名空间成员的qualified-id的形式为nested-name-specifier unqualified-id,则unqualified-id应命名为由nested-name-specifier或该命名空间的内联命名空间集(7.3.1)的元素指定的命名空间.[例如:
namespace A {
namespace B {
void f1(int);
}
using namespace B;
}
void A::f1(int){ } // ill-formed, f1 is not a member of A
Run Code Online (Sandbox Code Playgroud)
-end example] 但是,在这样的命名空间成员声明中,嵌套名称说明符可能依赖于using-directives来隐式提供嵌套名称说明符的初始部分.[例如:
namespace A {
namespace B {
void f1(int);
}
}
namespace C {
namespace D {
void f1(int);
}
}
using namespace A;
using namespace C::D;
void B::f1(int){ } // OK, defines A::B::f1(int)
Run Code Online (Sandbox Code Playgroud)
- 末端的例子]
因此,您可以省略嵌套名称说明符的初始部分,但不能省略任何中间部分.
| 归档时间: |
|
| 查看次数: |
912 次 |
| 最近记录: |