提问人:BethBorgov 提问时间:1/14/2021 最后编辑:BethBorgov 更新时间:1/14/2021 访问量:584
访问全局变量和命名空间变量
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,但我收到错误 我们也可以使用 e::x;但我的问题是为什么我们不能使用命名空间 e;
答:
在此示例中,似乎使命名空间中的名称在函数范围内可用。但是,它不会这样做。相反,它尝试将名称(在未确定的查找期间)从最近的封闭命名空间 和 注入到全局命名空间。因此变得模棱两可。using namespace e;
e
main
main
namespace e
main
namespace e
x
评论
using namespace e;
x
main
x
e
int x = 10;
让我们从另一个例子开始。
const int x = 10;
namespace e {
const int y = 5;
}
int main()
{
std::cout << e::y;
using namespace e;
std::cout << y;
}
全局命名空间中有值为 10 且名称为 name 的变量(可以简称为)和值为 5 且名称位于命名空间中的变量(必须称为 )。x
x
y
e
e::y
通过添加 ,可以将命名空间中的所有名称注入到全局命名空间中。这意味着全局命名空间现在包含 names 和 ,而命名空间包含 name 。现在,您可以使用 和 来引用具有 value 的变量。using namespace e;
e
x
y
e
y
5
y
e::y
现在,回到你的例子。如果我们改为:y
x
const int x = 10;
namespace e {
const int x = 5;
}
int main()
{
std::cout << e::x;
using namespace e;
std::cout << x;
}
有 in 全局命名空间 和 in 命名空间 。通过添加,您将命名空间中的所有名称注入到全局命名空间,因此现在全局命名空间包含名称 和 ,而命名空间包含名称 。看到问题了吗?全局命名空间包含两个名称,这会使编译器感到困惑。当您尝试在 name 下打印变量时,编译器在全局命名空间中查找名称并找到两个 .它无法选择您的意思是哪一个,因此它会抛出错误。x
x
e
using namespace e;
e
x
x
e
x
x
x
x
这就是为什么使用命名空间(特别是使用命名空间 std;
)被认为是邪恶的主要原因。人们可以通过更新库或引入新函数来轻松破坏工作代码。在这种情况下,编译器错误是最好的结果,但有时编译器可能会默默地将一个函数替换为另一个函数,因为它匹配得更好。
您仍然可以使用完全限定名称访问这两个变量:
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
}
评论
using namespace e;
::x
::e::x