使用指令与使用声明
Using directive vs using declaration
你能解释一下为什么这段代码有效并打印出 16;
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using namespace X;
}
int main()
{
std::cout << Y::p;
}
以及为什么这段代码会抛出多重声明错误
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using X::p;
}
int main()
{
std::cout << Y::p;
}
我听说 using 指令不仅仅是使用任何名称声明的过程,因为它的工作方式似乎不同
但是我不明白为什么,能不能详细解释一下??
类似地,这个可以很好地打印 16,如果我将指令替换为 X::p 的声明,它会抛出相同的错误
#include <iostream>
namespace X {
int p = 5;
}
int p = 16;
using namespace X;
int main()
{
std::cout << ::p;
std::cout << "\n";
return 0;
}
主要区别在于 using 声明就是一个声明。而 using 指令不是。听起来很愚蠢,我知道,但这就是区别的本质。前者实际上是在声明区域中添加声明,而后者只是使某些名称在声明区域中可用。
使名称在特定范围内可用,而不是声明它,旨在成为一个更弱的事情。如果有另一个同名声明,则在限定查找期间不考虑前者,如 [basic.scope.hiding]/4 所说:
During the lookup of a name qualified by a namespace name,
declarations that would otherwise be made visible by a using-directive
can be hidden by declarations with the same name in the namespace
containing the using-directive
这几乎可以解释您的第一个代码片段。由于 using 声明,该名称有一个声明,因此不考虑通过 using 指令显示的名称。不管哪个先来,宣言总是更有力。
您的第二个代码片段在 Y
中有两个 p
的声明。当涉及到这些时,适用通常的声明规则。第二个必须声明相同的东西,否则程序格式错误。仅此而已,真的。
最后,在您的第三个代码片段中,它与您的第一个代码片段中的更加相似。 [basic.lookup.qual]/4 是这样说的:
A name prefixed by the unary scope operator ::
([expr.prim]) is
looked up in global scope, in the translation unit where it is used.
The name shall be declared in global namespace scope or shall be a
name whose declaration is visible in global scope because of a
using-directive ([namespace.qual]). The use of ::
allows a global
name to be referred to even if its identifier has been hidden.
所以除了要查找的名称空间之外,其他一切都与您的第一个示例一样。你们都声明它,并通过 using 指令使其可用。我引用的第一段决定了必须选择哪一个。
你能解释一下为什么这段代码有效并打印出 16;
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using namespace X;
}
int main()
{
std::cout << Y::p;
}
以及为什么这段代码会抛出多重声明错误
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using X::p;
}
int main()
{
std::cout << Y::p;
}
我听说 using 指令不仅仅是使用任何名称声明的过程,因为它的工作方式似乎不同
但是我不明白为什么,能不能详细解释一下??
类似地,这个可以很好地打印 16,如果我将指令替换为 X::p 的声明,它会抛出相同的错误
#include <iostream>
namespace X {
int p = 5;
}
int p = 16;
using namespace X;
int main()
{
std::cout << ::p;
std::cout << "\n";
return 0;
}
主要区别在于 using 声明就是一个声明。而 using 指令不是。听起来很愚蠢,我知道,但这就是区别的本质。前者实际上是在声明区域中添加声明,而后者只是使某些名称在声明区域中可用。
使名称在特定范围内可用,而不是声明它,旨在成为一个更弱的事情。如果有另一个同名声明,则在限定查找期间不考虑前者,如 [basic.scope.hiding]/4 所说:
During the lookup of a name qualified by a namespace name, declarations that would otherwise be made visible by a using-directive can be hidden by declarations with the same name in the namespace containing the using-directive
这几乎可以解释您的第一个代码片段。由于 using 声明,该名称有一个声明,因此不考虑通过 using 指令显示的名称。不管哪个先来,宣言总是更有力。
您的第二个代码片段在 Y
中有两个 p
的声明。当涉及到这些时,适用通常的声明规则。第二个必须声明相同的东西,否则程序格式错误。仅此而已,真的。
最后,在您的第三个代码片段中,它与您的第一个代码片段中的更加相似。 [basic.lookup.qual]/4 是这样说的:
A name prefixed by the unary scope operator
::
([expr.prim]) is looked up in global scope, in the translation unit where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive ([namespace.qual]). The use of::
allows a global name to be referred to even if its identifier has been hidden.
所以除了要查找的名称空间之外,其他一切都与您的第一个示例一样。你们都声明它,并通过 using 指令使其可用。我引用的第一段决定了必须选择哪一个。