命名空间中定义类的样式的有效性

时间:2014-08-29 10:36:56

标签: c++

要点:

是否有任何文档(例如c ++标准)支持使用样式定义C ++类的有效性:

namespace N { class X; }
class N::X { ... }

详细信息:

我们在公司的一些代码中使用了几种样式来定义类:

// n_x.h - style 1
namespace N {
  class X;
}

class N::X {...}

// n_y.h - style 2
namespace N {
  class Y;
}

namespace N {
  class Y { ... };
}

这里的关键区别在于 style 1 中的class N::X style 2 中的namespace N { class Y {...}... ,即我们将中的Y类包装起来名称空间中的样式2 。

这两种风格对我来说都是有效的(我们在VS20xx和Clang上编译它们从来没有遇到过问题),但是一位同事质疑 style 1 是否有效作为我们用来分析我们的工具使用 style 1 时,代码无法正确识别 class X 作为命名空间的一部分。

我希望有人可以向我提供文档的参考,这些文档表明 style 1 是在C ++中定义类的有效方法。

4 个答案:

答案 0 :(得分:4)

是的,样式1有效。

[namespace.memdef]/2州:

  

命名空间的成员也可以通过显式限定在该命名空间之外定义(3.4.3.2)   如果已定义的实体已在命名空间中声明,则定义名称   并且该定义出现在包含声明的命名空间中的声明点之后   命名空间。

答案 1 :(得分:1)

也许Bjarne Stroustrup的书可以为你服务。

The C++ Programming Language, Fourth Edition的第14章开始:

-----(第392页)

  

[...]

     

14.2.1明确的资格认证

     

成员可以在名称空间定义中声明为winthin,稍后使用   namespace-name :: member-name表示法。

     

命名空间的成员必须是   使用这种表示法引入:

namespace namespace-name {
   // declarations and definitions
}
  

例如:

namespace Parser {
     double expr(bool); //declaration
     double term(bool);
     double prim(bool);
}

double val = Parser::expr(true); // use

double Parser::expr(bool b) //definition
{
    // ...
}
  

我们不能使用限定符语法(iso.7.3.1.2)在名称空间定义之外声明名称空间的新成员....

答案 2 :(得分:0)

§9[class] / p11:

  

如果 class-head-name 包含嵌套名称说明符,    class-specifier 应引用先前在类或命名空间中直接声明的类    nested-name-specifier 引用或在该命名空间的内联命名空间集(7.3.1)的元素中(即,不仅仅是继承的或   由 using-declaration 引入, class-specifier 应该   出现在封闭前一个声明的命名空间中。在这样的   case, class-head-name 嵌套名称说明符   定义不应以 decltype-specifier 开头。

class-head-name 是命名所定义类的东西的术语。 nested-name-specifier 是“::左侧所有内容的标准,包括::本身”。

答案 3 :(得分:0)

来自A.8 Classes [gram.class]

...
class-specifier:
    class-head { member-specification_opt }

class-head:
    class-key attribute-specifier-seq_opt class-head-name class-virt-specifier_opt
    base-clause_opt class-key attribute-specifier-seq_opt base-clause_opt

class-head-name:
    nested-name-specifier_opt class-name

class-virt-specifier:
    final

class-key:
    class
    struct
    union

因此,nested-name-specifier关键字与class-key之间允许使用class-name个可选项。 nested-name-specified中记录了A.4 Expressions [gram.expr]

nested-name-specifier:
    ::
    type-name ::
    namespace-name ::
    decltype-specifier ::
    nested-name-specifier identifier ::
    nested-name-specifier template_opt simple-template-id ::

因此namespace-name 在定义中有效。