目前为止C++中的using关键字主要有三中使用场景,从C++ 11开始新增了第三种。下面我们分别介绍一下。
指示使用某命名空间,对命名空间成员进行声明也就是说指明用哪个命名空间的成员
Using-directives:指示使用某命名空间,这也是最常见的使用方法
语法:
attr(optional) using namespace nested-name-specifier(optional) namespace-name;
attr: 应用到using的任意数量的属性,
nested-name-specifier: 名称和作用域解析运算符::的序列,以作用域解析运算符结尾。单个::引用全局命名空间。
namespace-name: 命名空间的名称。查找此名称时,只关注名称空间声明,也就是说只查找命名空间的名字。
using-directives只有在命名空间范围和块范围中才允许使用。从using-directives之后的任何名称的非限定名称查找的角度来看,直到它出现的作用域结束,namespace name中的每个名称都是可见的,就好像它是在最近的包含Using-directives和命名空间名称的封闭命名空间中声明的一样。
using-directives不会向它出现的声明区域添加任何名称(与using-declaration不同),因此不会阻止声明相同的名称。
using-directives对于非限定查找而言是可传递的:如果一个作用域包含一个指定名称空间名称的using-directives,而该指令本身又包含用于某个namespace-name-2的using-directives,其效果就像来自第二个命名空间的using-directives出现在第一个命名空间中。这些可传递名称空间发生的顺序不影响名称查找。
namespace A {
int i;
}
namespace B {
int i;
int j;
namespace C {
namespace D {
using namespace A; // all names from A injected into global namespace
int j;
int k;
int a = i; // i is B::i, because A::i is hidden by B::i
}
using namespace D; // names from D are injected into C
// names from A are injected into global namespace
int k = 89; // OK to declare name identical to one introduced by a using
int l = k; // ambiguous: C::k or D::k
int m = i; // ok: B::i hides A::i
int n = j; // ok: D::j hides B::j
}
}
namespace D {
int d1;
void f(char);
}
using namespace D; // introduces D::d1, D::f, D::d2, D::f,
// E::e, and E::f into global namespace!
int d1; // OK: no conflict with D::d1 when declaring
namespace E {
int e;
void f(int);
}
namespace D {
// namespace extension
int d2;
using namespace E; // transitive using-directive
void f(int);
}
void f() {
d1++; // error: ambiguous ::d1 or D::d1?
::d1++; // OK
D::d1++; // OK
d2++; // OK, d2 is D::d2
e++; // OK: e is E::e due to transitive using
f(1); // error: ambiguous: D::f(int) or E::f(int)?
f('a'); // OK: the only f(char) is D::f(char)