可以在两个不同的命名空间中声明同一个实体吗?

Can the same entity be declared in two different namespaces?

我对 c++ 标准中的 §7.3.4/6 有疑问:

If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.

这似乎表明存在在两个不同命名空间中声明同一实体的情况。否则就不需要措辞 "and the declarations do not declare the same entity"。

有这种情况的例子吗?请记住,using 声明并未声明任何实体。他们只是指在其他地方完成的实体声明(可能通过其他使用声明间接进行)。然而,使用声明将他们的名字引入声明区域,但那是另一回事。

另请记住,using-directives 也没有声明任何实体。

最后发现,命名空间成员的异常定义(使用限定名称的定义)并未在它们出现的命名空间中声明任何内容,而仅在目标命名空间中声明。

是的,extern。来自 [dcl.link]:

Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function. Two declarations for a variable with C language linkage with the same name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same variable.

例如:

namespace A {
    extern "C" int x;
}

namespace B {
    extern "C" int x;
}

extern "C" {
    int x;
}

namespace D {
    using namespace A;
    using namespace B;
}

A::xB::x(和 ::x)都是同一个实体。因此,D::x 不是病式的。


经过进一步思考,结合使用 using-declarations 和 using-directives,我们可以想出一个更简单的方法不依赖于 extern:

的例子
namespace A {
    int i;   
}

namespace B {
    using A::i;
}

namespace C {
    using A::i;
}

namespace D {
    using namespace B;
    using namespace C;
}

int main() {
    D::i = 4; // name lookup finds `i` declared in two different namespaces,
              // B and C. However, both of those declarations refer to the
              // same entity, A::i
}

但是使用声明确实可以声明实体的名称。来自 C++11 标准,§7.3.3[namespace.udecl]/1:

A using-declaration introduces a name into the declarative region in which the using-declaration appears.

using-declaration:

using typenameopt nested-name-specifier unqualified-id ;
using :: unqualified-id ;

using 声明中指定的成员名称在出现 using 声明的声明区域中声明。

namespace A{
void fun(){}
}
namespace B{
void fun(){}
}
int main()
{
using namespace A;
using namespace B;
fun()//ambiguous call here because this entity is present in both the namespaces 

}

在上面的代码中,对 fun 的调用不明确,因为查找将无法找到要调用的正确 fun。 第二个例子如下:

namespace N { namespace A {int i;} }

struct A {static int i;};

using namespace N;

int i = A::i; 

在后一种情况下,调用是不明确的,因为实体 'A' 存在于两个命名空间(N 和全局命名空间)中。 希望这会有所帮助