在不包含原始声明的命名空间中重新声明

6

命名空间成员可以在包含声明的命名空间中定义:

命名空间的成员也可以通过显式限定(3.4.3.2)定义的名称来定义在该命名空间之外,前提是要定义的实体已经在命名空间中声明, 并且定义出现在声明点所在的命名空间的内部

void f();

namespace N { void ::f() {} }       // illegal for definition

namespace N { void ::f(); }         // what about redeclaration?

可以在封装声明的命名空间中定义类:

如果类头名称包含嵌套名称限定符,则类说明符应该引用先前在该嵌套名称限定符所引用的类或命名空间中直接声明的类,或在该命名空间的内联名称空间集合(即不是仅通过using声明继承或引入),并且类说明符应该出现在封装先前声明的命名空间的命名空间中。在这种情况下,定义的类头名称的嵌套名称限定符不应以decltype说明符开头。

struct A;

namespace N { struct ::A {}; }      // illegal for definition

namespace N { struct ::A; }         // what about redeclaration?

我们对成员函数定义和静态数据成员定义有相同的规定。

所以我的问题是,重新声明(而不是定义)在不包含原始声明的命名空间中是否合法?

1个回答

2

关于struct ::A;[dcl.type.elab]/1使您的声明不合法:

如果一个 elaborated-type-specifier 是声明的唯一组成部分,则该声明无效,除非它是显式特化(14.7.3),显式实例化(14.7.2)或具有以下形式之一:class-key attribute-specifier-seq opt identifier;、friend class-key :: opt identifier;、friend class-key :: opt simple-template-id;、friend class-key nested-name-specifier identifier;、friend class-key nested-name-specifier template-opt simple-template-id;。
我在函数情况下没有看到问题; [dcl.meaning]/1 允许它:
declarator-id 被限定时,声明应该引用之前已经声明的类或命名空间成员,该限定符所指向的(或者,在命名空间的情况下,是该命名空间的内联命名空间集合中的元素)或其特化;[...] [Note: 如果限定符是全局 :: 范围解析运算符,则 declarator-id 引用在全局命名空间范围内声明的名称。 - end note]
然而,GCC 和 Clang 坚持认为重新声明(作为定义)必须出现在封闭的命名空间中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接