提问人:nriedlin 提问时间:8/7/2014 最后编辑:TemplateRexnriedlin 更新时间:8/7/2014 访问量:2071
是否可以在声明类成员的命名空间之外定义类成员?
Can class members be defined outside the namespace in which they are declared?
问:
有时我会发现如下代码(实际上一些类向导会创建这样的代码):
// C.h
namespace NS {
class C {
void f();
};
}
在实现文件中:
// C.cpp
#include "C.h"
using namespace NS;
void C::f() {
//...
}
我尝试过的所有编译器都接受这种代码(gcc、clang、msvc compileonline.com)。让我感到不舒服的是.从我的角度来看,它存在于一个对位于命名空间 NS 中的对象具有无条件访问权限的环境中的全局命名空间中。但在编译者看来,生活在.正如我尝试过的所有编译器都同意这种观点一样,他们可能是对的,但是这种观点在标准中的哪个地方得到支持?using namespace NS;
C::f()
void C::f()
namespace NS
答:
是的,语法确实是合法的,但不是,您的函数实际上确实存在于命名空间 NS 中。您看到的代码实际上等价于
namespace NS { void C::f() { /* ... } }
或
void NS::C::f() { /* ... */ }
这可能更类似于您习惯的。
由于 using 指令,您不仅可以在调用代码时省略 NS 部分,还可以省略其定义。标准有一个与您的代码匹配的示例(在粗体强调部分之后):
3.4.3.2 命名空间成员 [namespace.qual]
7 在命名空间成员的声明中,其中 declarator-id 是 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
—结束示例 ] 但是,在此类命名空间成员声明中, nested-name-specifier 可能依赖于 using 指令来隐式地 提供 nested-name-specifier 的初始部分。[ 示例:
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)
—结束示例 ]
因此,您可以省略嵌套名称说明符的初始部分,但不能省略任何中间部分。
评论
C::f()
C