关于 c++ 中命名空间的极其基本的问题

Extremely basic question about namespaces in c++

提问人:jaylse2 提问时间:10/19/2021 最后编辑:Vlad from Moscowjaylse2 更新时间:10/19/2021 访问量:101

问:

using namespace X;
    cout << var;
    using Y::var;
    cout << var;

假设我有一个命名空间 X 和一个命名空间 Y,它们都包含一个名为 var 的 int 类型的变量。当我说我想象发生的事情是,如果我使用一些不在全局名称范围内的变量,基本上发生的事情是,它没问题,我要寻找 var,但现在我也使用,这到底是什么意思?那只是说 var 和 Y::var 一样吗?但是,在这种情况下,发生了什么,它甚至不在那里寻找 var,因为我说我正在使用?using namespace X;namespace XY::varusing namespace XY::var

C++ 命名空间 name-lookup using-directives using-declaration

评论

0赞 Marek R 10/19/2021
只需创建一个示例并检查编译器将执行的操作即可。这是最好的学习方式。如果我们为您提供答案,您将在 5 分钟内忘记它。
2赞 eerorika 10/19/2021
取决于上下文。创建一个最小的可重现示例。与其描述程序是怎样的,不如向我们展示程序。
1赞 Raymond Chen 10/19/2021
有一个程序可以回答这些类型的问题。你可以问它
0赞 jaylse2 10/19/2021
我已经检查了编译器做了什么,我得到了我所期望的,即使用命名空间 X,我打印了 var,并在该命名空间内获得了 var,然后当我使用 Y::var 并将其打印出来时,我在 Y 命名空间内得到了 var,我只想问一下,以确保是我之前所说的,对吧?我说我正在使用 Y:::var 只是使用命名空间 X 覆盖?至少对于 var 来说,对不起,如果我没有很好地解释这一点,但是当我说我正在使用 Y::var 时,基本上是在说,好吧,如果您在代码中看到 var,请忽略我正在使用的其他命名空间,我说的是 Y::var?
0赞 Ted Lyngmo 10/19/2021
"我正在使用 Y:::var 只是使用命名空间 X 覆盖吗?- 它只覆盖它。其余的仍在使用。X::varX

答:

2赞 Vlad from Moscow 10/19/2021 #1

在 using 指令之后

using namespace X;

编译器使用非限定名称查找来查找以下语句中使用的名称var

cout << var;

由于 using 指令,它将在命名空间中找到变量。varX

This using 声明

using Y::var;

引入当前作用域和下一个语句中的命名空间中的变量varY

cout << var;

将使用命名空间中的变量。varY

这是一个演示程序。

#include <iostream>

namespace X
{
    int var = 1;
}

namespace Y
{
    int var = 2;
}

int main() 
{
    using namespace X;

    std::cout  << "var = " << var << '\n';

    using Y::var;

    std::cout  << "var = " << var << '\n';
}

程序输出为

var = 1
var = 2

也就是说,在函数 main 的块作用域中引入变量的 using 声明隐藏了在命名空间中声明的变量的声明。varvarX

事实上,下面简化的演示程序本质上与上述程序在名称查找方面的行为类似。

#include <iostream>

int var = 1;

int main() 
{
    std::cout  << "var = " << var << '\n';

    int var = 2;

    std::cout  << "var = " << var << '\n';
}
2赞 Caleth 10/19/2021 #2

是的,当你要求时会隐藏。前者是在此范围内声明的,后者仅影响不合格的查找。using Y::var;X::varvarY::var

using ns_name::name;

using-declaration:使命名空间中的符号可供非限定查找访问,就像在与此 using 声明出现的位置相同的类作用域、块作用域或命名空间中声明一样。namens_name

通过 using 声明引入命名空间范围的名称可以像使用任何其他名称一样使用,包括来自其他范围的限定查找

using namespace ns_name;

using-directive:从对 using 指令之后的任何名称进行非限定名称查找的角度来看,直到它出现的范围结束,每个名称都是可见的,就好像它是在最近的封闭命名空间中声明的一样,该命名空间同时包含 using 指令和 .ns_namens_name