【问题标题】:Accessing a global and namespace variable访问全局和命名空间变量
【发布时间】:2021-04-19 11:33:42
【问题描述】:

我正在尝试使用以下代码中的 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;

【问题讨论】:

标签: c++ namespaces using-directives


【解决方案1】:

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

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的变量,在命名空间e中有值为5、名称为y的变量(必须引用如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
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 你能用简单的话解释一下吗?
    • @BethBorgov using namespace e; 使编译器在 main 中搜索名称 x,就好像命名空间 e 中的 x 被声明在全局命名空间中的 int x = 10; 旁边一样。
    猜你喜欢
    • 2011-08-31
    • 2020-07-10
    • 2017-01-04
    • 1970-01-01
    • 2012-03-13
    • 2012-05-11
    • 2011-03-25
    • 1970-01-01
    • 2015-04-22
    相关资源
    最近更新 更多