gpt4 book ai didi

c++ - 确定哪个成员在 namespace 中可见

转载 作者:太空狗 更新时间:2023-10-29 20:25:05 25 4
gpt4 key购买 nike

考虑以下代码片段

#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

我知道在这种情况下,如果垃圾邮件包含该成员,它将引用该成员。但是,如果没有,则会找到 using 指令的名称并引用 fallbacks::bar。

但我找不到任何可靠的来源来支持上述说法。

最佳答案

该标准的

第 3.4.3 节 描述了限定名称查找。特别是,部分 3.4.3.2 描述了命名空间成员的查找。

3.4.3.2.2: For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S'(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the union of S(N_i,m) for all namespaces N_i nominated by using-directives in X and its inline namespace set.

(来源: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,则通过 using 指令在 Spam 中声明的任何命名空间或 bar 将被搜索,并递归应用此逻辑,直到:

  1. 发现一个命名空间包含bar,或者
  2. 可能的搜索路径已经用尽,在这种情况下程序是病式的。

关于c++ - 确定哪个成员在 namespace 中可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24930921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com