【问题标题】:shadowing of functions in namespaces命名空间中的函数阴影
【发布时间】:2024-01-02 16:56:01
【问题描述】:

假设你有以下代码

namespace a{
  struct S{};
  //void f(int){}
}

namespace b{
  struct T{};
}


struct X{};

void f(X){}
void f(b::T){}
void f(a::S){}



namespace a{
  void g(){

    S s;b::T t; 
    X x;
    f(x);
    f(s);
    f(t);
  }

}

int main(){
  a::g();
}

如果void f(int){} 定义在命名空间a 中(第3 行未注释),它会影响void f(b::T){}void f(a::S){} 的后续定义,但不会影响void f(X){}。 为什么?

【问题讨论】:

  • 我认为它确实隐藏了外部f,并且f(c) 在同一个命名空间中使用f(int)
  • 同样的事情发生在 struct X instread of char
  • 不,那是另一回事。如果参数和函数声明在同一个命名空间(包括全局命名空间)中,函数仍然可以找到。
  • @BoPersson 谢谢!!这正是重点!
  • @BoPersson:如果您将其写为答案,我会将其标记为明确的答案。实际上,命名空间 c{ struct Y{}; void f(Y){} } 和 f(y) 有效

标签: c++ namespaces method-hiding


【解决方案1】:

它将调用 f(char)f(int) 的阴影,因为 char 可以隐式转换为 int。 http://liveworkspace.org/code/8d7d4e0bc02fd44226921483a910a57b

编辑。

命名空间A中有函数f(int)。全局命名空间中有函数f(A::S)。我们试图从函数 g 中调用 f(s),其中 s 是 A::S,该函数位于命名空间 A 中,编译器发现,该函数应应用 S (A::S),但命名空间 A 中没有这样的函数,所以编译器停止并给出错误。 http://liveworkspace.org/code/5f989559d2609e57c8b7a655d5b1cebe

在全局命名空间中有函数f(B::T)。试图在命名空间 A (f(int)) 和命名空间 B 中查找(因为 arg-type 在命名空间 B 中),没有找到,编译器停止。 http://liveworkspace.org/code/4ebb0374b88b29126f85038026f5e263

在全局命名空间中有函数f(X)X 在全局命名空间中,查看命名空间A (f(int)) 和在全局命名空间中(找到f(X)) - 一切正常。 http://liveworkspace.org/code/c9ef24db2b5355c4484aa99884601a1a

有关更多信息,请阅读 C++ 标准(草案 n3337)的第 3.4.2 节。或者,更简单的http://en.wikipedia.org/wiki/Argument-dependent_name_lookup

【讨论】:

  • 谢谢。我修改了代码以表明同样的事情发生在一个不可转换为 int 的结构上
  • 你知道它为什么不影响 f(X) 吗?
  • 但是struct X 被声明在与f(X) 相同的命名空间中,因此其他规则适用于那里。见Argument Dependent Lookup