可以在两个不同的命名空间中声明同一个实体吗?
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::x
和 B::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 typename
opt 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 和全局命名空间)中。
希望这会有所帮助
我对 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::x
和 B::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 typename
opt 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 和全局命名空间)中。 希望这会有所帮助