要点:
是否有任何文档(例如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 {...}...
,即我们将
这两种风格对我来说都是有效的(我们在VS20xx和Clang上编译它们从来没有遇到过问题),但是一位同事质疑 style 1 是否有效作为我们用来分析我们的工具使用 style 1 时,代码无法正确识别 class X 作为命名空间的一部分。
我希望有人可以向我提供文档的参考,这些文档表明 style 1 是在C ++中定义类的有效方法。
答案 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
在定义中有效。