有哪些命名空间以及规则是什么?

gez*_*eza 9 c++ namespaces

注意:这个问题是关于name space,而不是namespace

C++ 标准有一些对 的引用name space,但我没有看到它的定义。标准说标签和宏位于不同的命名空间中。所有其他引用name space都在 C/C++ 兼容性部分,如下所示(当前草案):

这是 C 和 C++ 之间为数不多的可归因于新的 C++ 名称空间定义的不兼容性之一,其中名称可以在单个范围内声明为类型和非类型,导致非类型名称隐藏类型名称并要求使用关键字 class、struct、union 或 enum 来引用类型名称。这个新的命名空间定义为 C++ 程序员提供了重要的符号便利,并有助于使用户定义类型的使用尽可能类似于基本类型的使用。

这个新的命名空间定义是什么?我在哪里可以在标准中找到它?具体规则是什么?规则似乎比“非类型隐藏类型”更复杂。就像,这不会编译:

typedef int Foo; // Foo is a type
void Foo();      // not a type, but compile error, instead of hiding
Run Code Online (Sandbox Code Playgroud)

但这确实:

struct Foo { }; // Foo is a type as well
void Foo();     // This hides the type Foo. "struct Foo" refers to the type
Run Code Online (Sandbox Code Playgroud)

这也不能编译:

struct Foo { };   // Type
namespace Foo { } // Non-type, but compiler error instead of hiding
Run Code Online (Sandbox Code Playgroud)

dfr*_*fri 2

名称空间术语在 ISO C 标准中可能更为完善;引用ISO C11

6.2.3 标识符的命名空间

如果特定标识符的多个声明在翻译单元中的任何一点可见,则语法上下文会消除引用不同实体的使用的歧义。因此,不同类别的标识符有单独的名称空间,如下所示:

  • 标签名称(通过标签声明和使用的语法消除歧义);
  • 结构、联合和枚举的标签(通过关键字 struct、union 或 enum 的 any32 消除歧义);
  • 组织或工会的成员;每个结构或联合对其成员都有一个单独的名称空间(通过用于通过 . 或 -> 运算符访问成员的表达式类型消除歧义);
  • 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量声明)。

然而,C++ 的新命名空间定义在时间上并不是最近的,并且自ISO C++ 标准于 98 年推出以来就以其当前形式在 [diff.class]/1 中进行了描述。根据 OP 引用的 [diff.class]/1,它仅在与 ISO C 不同的上下文中以任何长度提及。

Afaics 我们需要求助于 ISO C11/6.2.3 并将其与 ISO C++ 标准的 [diff.class]/1 相结合,以对C++ 的(新)命名空间定义进行内聚且完整的描述,而不是我们对 ISO 的鞭笞例如[basic.scope.hiding][class.name]/2[stmt.label]/1[cpp.replace]/8等的 C++ 标准,看看它如何以及在哪里应用。

[班级名称]/2

类声明将类名引入到声明它的范围中,并隐藏封闭范围中该名称的任何类、变量、函数或其他声明。[...]

[stmt.标签]/1

[...]标签有自己的名称空间并且不干扰其他标识符[...]

[cpp.替换]/1

[...] 宏名称只有一个名称空间。[...]