成员的struct与命名空间的潜在范围

Jos*_* D. 3 c++ scope namespaces declaration

参考这段代码:

namespace Y {
  char f() { return y; } // error: y was not declared in this scope
  char y;
}

struct X {
  char  f() { return x; } // OK
  char  x;
};
Run Code Online (Sandbox Code Playgroud)

根据basic.scope.namespace#1:

命名空间定义的声明性区域是其namespace-body.在namespace-body中声明的实体被称为命名空间的成员,并且这些声明引入命名空间的声明性区域的名称被称为命名空间的成员名称.它的潜在范围包括从名称的声明点开始的命名空间.

质询

  1. 说错误是由于Y::y尚未声明的事实是否正确Y::f()

  2. 我无法理解为什么namespace在宣言期间没有为会员"重新登记",而struct有.什么原因可能导致不允许这种行为?标准是否有相似之处?

Sto*_*ica 5

说错误是由于Y::y尚未声明的事实是否正确Y::f()

是.

我无法理解为什么在声明期间没有"名称空间成员"的"重新加载",而对于struct来说.什么原因可能导致不允许这种行为?标准是否有相似之处?

命名空间与类相反的最大障碍是它们永远不会"封闭".您始终可以通过在另一个翻译单元中重新打开成员并在其中声明更多内容来将成员添加到名称空间.但是,对于其所有成员,类声明必须完全出现在单个翻译单元中.以后没有任何补充.

[class.mem]/1

类定义中的成员规范声明了该类的完整成员集; 其他任何成员都无法添加.

命名空间的问题是难以处理的.但是课程只需要更多,更本地化的工作.

因此,对于语言设计者和编译器编写者来说,要求命名空间声明在使用之前出现要容易得多.

您还应注意,您只能在定义中的特定位置集中使用该类的其他成员.

[class.mem]/6

}类说明符结束时,类被视为完全定义的对象类型([basic.types])(或完整类型).在类成员规范中,该类在函数体,默认参数,noexcept-specifiers和默认成员初始化器(包括嵌套类中的这类事物)中被视为完整.否则,它在其自己的类成员规范中被视为不完整 .