访问全局变量和命名空间变量
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
注入到最近的 main
和 namespace 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
中的所有名称注入 到全局命名空间中。这意味着全局命名空间现在包含名称 x
和 y
,而命名空间 e
包含名称 y
。您现在可以使用 y
和 e::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
中的所有名称注入全局命名空间,因此现在全局命名空间包含名称 x
和 x
,而命名空间 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
}
我正在尝试在以下代码中使用 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
注入到最近的 main
和 namespace 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
中的所有名称注入 到全局命名空间中。这意味着全局命名空间现在包含名称 x
和 y
,而命名空间 e
包含名称 y
。您现在可以使用 y
和 e::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
中的所有名称注入全局命名空间,因此现在全局命名空间包含名称 x
和 x
,而命名空间 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
}