请考虑以下代码段
#include <iostream>
#include <memory>
namespace Foo {
void bar() {
std::cout<<"FOO::BAR"<<std::endl;
}
}
namespace Spam {
void bar() {
std::cout<<"SPAM::BAR"<<std::endl;
}
}
namespace fallbacks {
using Foo::bar;
}
namespace Spam {
using namespace fallbacks;
}
int main() {
Spam::bar();
}
输出
SPAM::BAR
据我所知,在这种情况下,如果Spam包含该成员,它将引用它。但是如果没有,那么将找到using指令的名称并引用fallbacks :: bar。
但是我找不到任何可靠的来源来支持上述陈述。
答案 0 :(得分:5)
第3.4.3节描述了限定名称查找。特别是,部分 3.4.3.2 描述了命名空间成员的查找。
3.4.3.2.2:对于名称空间
X
和名称m
, 命名空间限定的查找集S(X,m)
定义如下:让S'(X,m)
是m
中X
和内联的所有声明的集合 命名空间集X
(7.3.1)。如果S'(X,m)
不为空,则S(X,m)
为空S'(X,m)
;否则,S(X,m)
是所有名称空间的S(N_i,m)
的并集 由N_i
中的 using-directives 及其内联命名空间集提名的X
。
(来源:ISO / IEC 14882:2011:C ++标准)
给出以下示例:
int x;
namespace Y {
void f(float);
void h(int);
}
namespace Z {
void h(double);
}
namespace A {
using namespace Y;
void f(int);
void g(int);
int i;
}
namespace B {
using namespace Z;
void f(char);
int i;
}
namespace AB {
using namespace A;
using namespace B;
void g();
}
void h()
{
AB::g(); // g is declared directly in AB,
// therefore S is { AB::g() } and AB::g() is chosen
AB::f(1); // f is not declared directly in AB so the rules are
// applied recursively to A and B;
// namespace Y is not searched and Y::f(float)
// is not considered;
// S is { A::f(int), B::f(char) } and overload
// resolution chooses A::f(int)
AB::f(’c’); // as above but resolution chooses B::f(char)
AB::x++; // x is not declared directly in AB, and
// is not declared in A or B , so the rules are
// applied recursively to Y and Z,
// S is { } so the program is ill-formed
AB::i++; // i is not declared directly in AB so the rules are
// applied recursively to A and B,
// S is { A::i , B::i } so the use is ambiguous
// and the program is ill-formed
AB::h(16.8); // h is not declared directly in AB and
// not declared directly in A or B so the rules are
// applied recursively to Y and Z,
// S is { Y::h(int), Z::h(double) } and overload
// resolution chooses Z::h(double)
}
(来源:ISO / IEC 14882:2011:C ++标准)
在您的示例中,如果Spam
包含bar
,则设置S
包含{Spam::bar}
并且查找停止。如果名称空间Spam
不包含bar
,则将搜索在Spam中通过bar
指令声明的任何名称空间或using
,并且递归应用此逻辑,直到:< / p>
bar
或答案 1 :(得分:1)
在3.4.3.2 C ++标准的命名空间成员的以下段落中描述了限定名称的相应名称查找
2对于名称空间X和名称m,名称空间限定查找集S(X,m)定义如下:设S0(X,m)是X中m和内联名称空间的所有声明的集合X的集合(7.3.1)。如果S0(X,m)不为空,则S(X,m)为S0(X,m);否则,S(X,m)是由X中的using指令及其内联命名空间集指定的所有名称空间Ni的S(Ni,m)的并集。
3鉴于X :: m(其中X是用户声明的命名空间),或者给定:: m(其中X是全局命名空间),如果S(X,m)是空集,则程序生病-formed。否则,如果S(X,m)只有一个成员,或者引用的上下文是using-declaration(7.3.3),则S(X,m)是m的必需声明集。否则,如果使用m不允许从S(X,m)中选择唯一声明,则该程序格式不正确。
在你的情况下,如果要遵循引号&#34; 设S0(X,m)是X中m的所有声明和X的内联命名空间集(7.3.1)的集合。如果S0(X,m)不为空,则S(X,m)为S0(X,m); &#34; S(垃圾邮件,栏)由垃圾邮件中的一个条形声明组成。此声明是垃圾邮件中唯一的声明。所以这个名字会被找到。