访问全局变量和命名空间变量

Accessing a global and namespace variable

我正在尝试在以下代码中使用 using 指令访问变量 x:

#include <iostream>
using namespace std;
int x = 10;
namespace e {
int x = 5;
}
int main() {
using namespace e; // Because of this line compiler shows error
cout << x;
return 0;
}

通常我们使用以下行来访问 x 但我收到错误 我们也可以使用 using e::x; 但我的问题是为什么我们不能使用 using namespace e;

在此示例中,using namespace e; 似乎使名称空间 e 中的名称在 main 函数范围内可用。但是它不会这样做。相反,它尝试将名称(在 main 中的非限定查找期间)从 namespace e 注入到最近的 mainnamespace e 的封闭命名空间,即全局命名空间。因此x变得模棱两可。

让我们从另一个例子开始。

const int x = 10;

namespace e {
const int y = 5;
}

int main()
{
std::cout << e::y;
using namespace e;
std::cout << y;
}

在全局命名空间(可以简称为x)中存在值为10、名称为x的变量,在命名空间[中存在值为5、名称为y的变量e(必须引用为 e::y)。

通过添加 using namespace e;,您 将命名空间 e 中的所有名称注入 到全局命名空间中。这意味着全局命名空间现在包含名称 xy,而命名空间 e 包含名称 y。您现在可以使用 ye::y.

来引用值为 5 的变量

现在,回到你的例子。如果我们将 y 更改为 x:

const int x = 10;

namespace e {
const int x = 5;
}

int main()
{
std::cout << e::x;
using namespace e;
std::cout << x;
}

全局命名空间中有 x,命名空间 e 中有 x。通过添加 using namespace e;,您将命名空间 e 中的所有名称注入全局命名空间,因此现在全局命名空间包含名称 xx,而命名空间 e 包含名称x。看到问题了吗?全局命名空间包含两个名称 x,这会使编译器感到困惑。当您尝试打印名称 x 下的变量时,编译器在全局命名空间中查找名称并找到两个 x。它无法选择您指的是哪一个,因此会抛出错误。

这是using namespace (particularly using namespace std;) is considered evil的主要原因。可以通过更新库或引入新函数轻松破坏工作代码。在这种情况下,编译器错误是最好的结果,但有时编译器可能会默默地用一个函数替换另一个函数,因为它匹配得更好。

您仍然可以使用 完全限定名称:

访问这两个变量
int main()
{
using namespace e;
std::cout << ::x << " "; //x from global with fully quafilied name
std::cout << ::e::x << " "; //x from namespace e with fully qualified name
std::cout << e::x; //not fully qualified, but not ambiguous either - only one x in namespace e
}