可以在包含声明命名空间的命名空间中定义命名空间成员:
命名空间的成员也可以通过显式限定在该命名空间之外定义(3.4.3.2) 如果已定义的实体已在命名空间中声明,则定义名称 并且该定义出现在包含声明的命名空间中的声明之后 命名空间
void f();
namespace N { void ::f() {} } // illegal for definition
namespace N { void ::f(); } // what about redeclaration?
可以在包含声明命名空间的命名空间中定义类:
如果类头名包含嵌套名称说明符,则类说明符应引用一个类 以前在嵌套名称说明符引用的类或命名空间中直接声明,或者在 该命名空间的内联命名空间集(7.3.1)的元素(即,不仅仅是由...继承或引入 使用声明),和类说明符应出现在包含前一个声明的命名空间中。 在这种情况下,定义的类头名的嵌套名称说明符不应以a开头 decltype说明符。
struct A;
namespace N { struct ::A {}; } // illegal for definition
namespace N { struct ::A; } // what about redeclaration?
我们对成员函数定义和静态数据成员定义也有相同的规则。
所以我的问题是重新声明(不是定义)在没有包含原始声明的命名空间中是否合法?
答案 0 :(得分:1)
关于struct ::A;
,[dcl.type.elab]/1使您的声明格式不正确:
如果 elaborated-type-specifier 是a的唯一成分 声明,声明格式不正确,除非是明确的 专门化(14.7.3),显式实例化(14.7.2)或它 具有以下形式之一:
class-key attribute-specifier-seq opt 标识符
;
friend
class-key::
opt 标识符;
friend
class-key::
opt simple-template-id;
friend
< em> class-key nested-name-specifier identifier;
friend
class-key nested-name-specifiertemplate
opt simple-template-id;
我在功能案例中没有看到问题; [dcl.meaning]/1允许它:
当 declarator-id 是合格的,声明应引用先前声明的类或命名空间的成员 限定符所引用的(或者,在命名空间的情况下,该命名空间的内联命名空间集合的元素(7.3.1))或其特化; [...] [注意:如果限定符是全局
::
范围解析运算符,则 declarator-id 引用声明的名称 在全局命名空间范围内。 - 结束记录]
但是,GCC和Clang都坚持认为重新声明作为定义必须在封闭的命名空间中进行。