【问题标题】:using namespace for function-member definition使用命名空间来定义函数成员
【发布时间】:2017-12-27 09:03:04
【问题描述】:

我在.h 文件中有以下类定义:

namespace N {
    struct S {
        S(); // no definition for member here    
    };
}

我想在.cpp 文件中编写类构造函数(一般成员)的定义。我考虑以下两种情况:

  1. namespace N {
        S::S() { /* definition */ }  
    }
    
  2. using namespace N;
    S::S() { /* definition */ }  
    

我有点困惑为什么第二个工作,因为直到今天才看到这种方式定义。为什么第二个有效?引用标准中的一些内容将不胜感激。

使用一种方法而不是另一种方法有哪些细微差别?我应该更喜欢第一种形式还是第二种形式?

【问题讨论】:

  • 如果(2)起作用,我会感到非常惊讶。显然 (1) 和一般的范围界定是首选。
  • @HenriMenke 在我看来using namespace 实际上是用于“使用”,即调用函数、使用变量等,但不是用于定义。例如。你不能以同样的方式定义一个类。
  • 可以,但没有限制。 “使用指令指定的命名空间中的声明在包含使用指令的命名空间中变得可见;”命名空间也可以是翻译单元的全局命名空间。
  • 我认为您必须将第二个版本用于未命名的命名空间。

标签: c++ namespaces language-lawyer


【解决方案1】:

(2) 起作用的原因是因为这两个:

  1. [class.mfct]/4

    如果成员函数的定义在词法上在其类之外 定义,成员函数名称应由其类限定 使用​::​运算符命名。

  2. [namespace.udir]/2(强调我的)

    使用指令指定指定命名空间中的名称 可以在 using 指令出现的范围内使用 使用指令。在不合格名称查找期间,名称出现 好像它们是在最近的封闭命名空间中声明的 包含使用指令和指定的命名空间。 [ 笔记: 在此上下文中,“包含”是指“直接或间接包含”。 — 尾注 ]

该指令只是让您将 S 命名为 :: 运算符,就像您在 N 命名空间中一样(就像您在 (1) 中一样)。但我不会那样做。范围界定很好。定义也应该有范围。

【讨论】:

    【解决方案2】:

    在这个特定示例中,您在命名空间中仅声明了一个结构,并在单独的 .cpp 文件中定义了函数,因此使用 1 或 2 无关紧要。

    如果您在命名空间中声明了任何其他标识符,那么 1 应该优先于 2,因为 using 声明类型违背了拥有命名空间的目的。

    【讨论】: