使用指令如何以及在何处注入成员名称



AFAIK using指令在最近的封闭命名空间中公开或注入命名空间的所有名称。这是来自C++引物:

相反,using指令使命名空间的整个内容可用。通常,命名空间可能包含无法出现在本地作用域中的定义。因此,using指令被视为出现在最近的封闭命名空间范围中。

在最简单的情况下,假设我们有一个命名空间a和一个函数f,两者都是在全球范围内定义。如果f对a有使用指令,那么在f中,就好像a中的名称在定义f 之前出现在全局范围中一样

来自cppreference:

  1. using指令:从对using指令之后的任何名称进行非限定名称查找的角度来看,直到它出现的范围结束,ns_name中的每个名称都是可见的,就好像它是在最近的包含using指令和ns_name的封闭命名空间中声明的一样
#include <iostream>
int x = 1;
int y = 2;
int z = 3;
namespace A{
namespace B{
int x = 5;
int y = 10;
int z = 0;
}
void foo(){
using namespace A::B;
std::cout << x << 't' << y << 't' << z << 'n'; // x, y, z are not ambiguous
}
}
namespace AA{
namespace BB{
void bar(){
using namespace A::B;
std::cout << x << 't' << y << 't' << z << 'n'; // x, y, z are ambiguous
}
}
}

int main(){
A::foo(); // works fine
AA::BB::bar(); // fails to compile
std::cout << "ndone!n";
}
  • 为什么第一个版本运行良好(函数A::foo()(,而第二个版本(AA::BB::bar()(不正常?

  • 我发现"将名称注入与using指令和命名空间定义最近的命名空间"有点令人困惑。

是的,这很复杂,但你引用的话准确地解释了发生了什么。在你的第一个例子中(将变量数量减少到1(:

int x = 1;
namespace A {
namespace B {
int x = 5;
}
void foo(){
using namespace A::B;
std::cout << x << 'n';
}
}

最近的命名空间是A。从本质上讲,该代码相当于

int x = 1;
namespace A {
int x = 5;
void foo(){
std::cout << x << 'n'; // x from NS a.
}
}

x将是在a中定义的名称,并且将被使用。

在第二个例子中,

namespace AA {
namespace BB {
void bar() {
using namespace A::B;
std::cout << x << 'n'; 
}
}
}

最近的命名空间将是全局命名空间。从本质上讲,该代码相当于

int x = 1;
int x = 5;
namespace AA {
namespace BB {
void bar() {
std::cout << x << 'n'; 
}
}
}

由于x不能在同一范围内重新定义,因此此代码的格式可能不正确。

最新更新