C++:使用声明和指令的顺序会影响选择吗?
C++: Does the order of using declaration and directive affect the selection?
下面是示例代码
#include <iostream>
using namespace std;
namespace A {
void f() { cout << "a" << endl; }
}
namespace B {
void f() { cout << "b" << endl; }
}
namespace C {
using namespace A;
using namespace B;
using A::f;
}
namespace D {
using A::f;
using namespace A;
using namespace B;
}
int main()
{
C::f();
D::f();
}
当我在 Visual Studio 2015 年尝试时,这会打印 "a" 两次,这种行为是由标准定义的还是特定于此实现的?
cppreference.com 中的以下两段应该解释该行为:
Using-directive [using namespace A;
] does not add any names to the declarative region in which it appears (unlike the using-declaration [using A::f;
]), and thus does not prevent identical names from being declared.
Using-directives are transitive for the purposes of unqualified lookup: if a scope contains a using-directive that nominates a namespace-name, which itself contains using-directive for some namespace-name-2, the effect is as if the using directives from the second namespace appear within the first. The order in which these transitive namespaces occur does not influence name lookup.
简单地说:using A::f;
就好像你在这个命名空间中声明了函数。 using namespace A;
只会导致类型名查找的行为就好像当前命名空间(C
或 D
)在您的例子中是 A
.
中的命名空间一样
这类似于
namespace A {
void f() { cout << "a" << endl; }
namespace B {
void f() { cout << "b" << endl; }
}
}
和
namespace A {
namespace B {
void f() { cout << "b" << endl; }
}
void f() { cout << "a" << endl; }
}
是等价的。
它是由标准定义的(像这样的东西总是这样)。要意识到的关键是,您的各种 using namespace
行对您的程序没有任何影响。
using namespace Foo
是一个 "using directive",它会影响范围内代码执行的名称查找。也就是说,如果您的 namespace C {}
块中的某些后续函数试图找到某个名为 foo
的对象,则 A
和 B
将位于编译器将搜索的位置中一个foo
。相反,如果后面的代码引用 C::foo
,它不会改变编译器查找的位置。单个块中两个连续 using namespace
的顺序无关紧要,因为每个块都具有完整的效果,直到块结束。
您能够在 C
或 D
中找到 f
的原因是 "using declaration" using A::f
。与 using 指令不同,using 声明具有将名称注入范围的效果,这样其他代码就可以在该范围内引用该名称。
下面是示例代码
#include <iostream>
using namespace std;
namespace A {
void f() { cout << "a" << endl; }
}
namespace B {
void f() { cout << "b" << endl; }
}
namespace C {
using namespace A;
using namespace B;
using A::f;
}
namespace D {
using A::f;
using namespace A;
using namespace B;
}
int main()
{
C::f();
D::f();
}
当我在 Visual Studio 2015 年尝试时,这会打印 "a" 两次,这种行为是由标准定义的还是特定于此实现的?
cppreference.com 中的以下两段应该解释该行为:
Using-directive [
using namespace A;
] does not add any names to the declarative region in which it appears (unlike the using-declaration [using A::f;
]), and thus does not prevent identical names from being declared.Using-directives are transitive for the purposes of unqualified lookup: if a scope contains a using-directive that nominates a namespace-name, which itself contains using-directive for some namespace-name-2, the effect is as if the using directives from the second namespace appear within the first. The order in which these transitive namespaces occur does not influence name lookup.
简单地说:using A::f;
就好像你在这个命名空间中声明了函数。 using namespace A;
只会导致类型名查找的行为就好像当前命名空间(C
或 D
)在您的例子中是 A
.
这类似于
namespace A {
void f() { cout << "a" << endl; }
namespace B {
void f() { cout << "b" << endl; }
}
}
和
namespace A {
namespace B {
void f() { cout << "b" << endl; }
}
void f() { cout << "a" << endl; }
}
是等价的。
它是由标准定义的(像这样的东西总是这样)。要意识到的关键是,您的各种 using namespace
行对您的程序没有任何影响。
using namespace Foo
是一个 "using directive",它会影响范围内代码执行的名称查找。也就是说,如果您的 namespace C {}
块中的某些后续函数试图找到某个名为 foo
的对象,则 A
和 B
将位于编译器将搜索的位置中一个foo
。相反,如果后面的代码引用 C::foo
,它不会改变编译器查找的位置。单个块中两个连续 using namespace
的顺序无关紧要,因为每个块都具有完整的效果,直到块结束。
您能够在 C
或 D
中找到 f
的原因是 "using declaration" using A::f
。与 using 指令不同,using 声明具有将名称注入范围的效果,这样其他代码就可以在该范围内引用该名称。