是否可以在声明它们的名称空间之外定义类成员? [英] Can class members be defined outside the namespace in which they are declared?

查看:102
本文介绍了是否可以在声明它们的名称空间之外定义类成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候我会找到类似以下的代码(实际上有些类向导会创建这样的代码):

Sometimes I find code like the following (actually some class-wizards create such code):

// C.h
namespace NS {

class C {
    void f();
};

}

并在实施文件中:

// C.cpp
#include "C.h"

using namespace NS;
void C::f() {
  //...
}

我尝试过的所有编译器都接受这种代码(gcc,clang,msvc,compileonline.com). using namespace NS;使我感到不舒服.从我的角度来看,C::f()驻留在全局名称空间中,该环境对存在于名称空间NS中的对象具有不合格的访问权限.但是编译器认为void C::f()存在于namespace NS中.当我尝试过的所有编译器都同意这种观点时,他们可能是正确的,但是这种观点在标准中有何根据?

All the compilers I tried accept that kind of code (gcc, clang, msvc, compileonline.com). What makes me feel uncomfortable is the using namespace NS;. From my point of view C::f() lives in the global namespace in an environment that has unqualified access to objects living in namespace NS. But in the compiler's opinion void C::f() lives in namespace NS. As all compilers I tried share that point of view they are probably right, but where in the standard is this opinion backed?

推荐答案

是的,语法确实合法,但是否,您的函数确实存在于命名空间NS中 >.您所看到的代码实际上等效于

Yes, the syntax is indeed legal, but no, your function actually does live in the namespace NS. The code you are seeing is actually equivalent to

namespace NS { void C::f() { /* ... } }

void NS::C::f() { /* ... */ }

这可能更像您的习惯.

由于using指令,您不仅可以在调用代码中而且在其定义中省略NS部分.该标准有一个与您的代码匹配的示例(在粗体强调的部分之后):

Because of the using-directive you can omit the NS part not only in calling code, but also in its definition. The Standard has an example that matches your code (after the bold emphasized part):

3.4.3.2命名空间成员[namespace.qual]

7在名称空间成员的声明中,其中declarator-id 鉴于命名空间的qualified-id,它是一个qualified-id 成员具有嵌套名称说明符unqualid-id的形式 unqualified-id应命名由以下名称指定的名称空间的成员: 嵌套名称说明符或内联名称空间集的元素 (7.3.1)的名称空间. [示例:

7 In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-id for the namespace member has the form nested-name-specifier unqualified-id the unqualified-id shall name a member of the namespace designated by the nested-name-specifier or of an element of the inline namespace set (7.3.1) of that namespace. [ Example:

namespace A {
  namespace B {
    void f1(int);
  }
  using namespace B;
}
void A::f1(int){ } // ill-formed, f1 is not a member of A

-结束示例] 但是,在此类名称空间成员声明中, 嵌套名称说明符可能依赖using指令来隐式地使用 提供嵌套名称说明符的初始部分. [示例:

—end example ] However, in such namespace member declarations, the nested-name-specifier may rely on using-directives to implicitly provide the initial part of the nested-name-specifier. [ Example:

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)

-结束示例]

—end example ]

因此,您可以省略嵌套名称说明符的初始部分,但没有任何中间部分.

So you may omit the initial part of the nested-name-specifier, but not any intermediate part.

这篇关于是否可以在声明它们的名称空间之外定义类成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆