命名空间中的函数阴影化

5
假设您有以下代码:
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();
}

如果在命名空间a中定义了void f(int){}(第3行没有被注释掉),那么它会遮盖后面的void f(b::T){}void f(a::S){}的定义,但不包括void f(X){}
为什么呢?

1
我认为它确实隐藏了外部的 f,并且在相同的命名空间中时,f(c) 使用 f(int) - Bo Persson
使用结构体X而不是char时,同样的事情会发生。 - Fabio Dalla Libera
1
不,那是另一件事。如果参数和函数在同一个命名空间(包括全局命名空间)中声明,函数仍然可以被找到。 - Bo Persson
@BoPersson 谢谢您!! 这正是重点所在! - Fabio Dalla Libera
@BoPersson:如果您将其编写为答案,我将将其标记为最终答案。实际上,命名空间c { 结构Y {}; 空调f(Y){} }和f(y)工作 - Fabio Dalla Libera
1个回答

3

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

编辑。

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

在全局命名空间中有一个名为f(B::T)的函数。尝试在命名空间A中查找(f(int))和在命名空间B中查找(因为参数类型在命名空间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的结构体发生了相同的事情。 - Fabio Dalla Libera
你有任何想法为什么它不能阴影f(X)吗? - Fabio Dalla Libera
1
但是struct X在与f(X)相同的命名空间中声明,因此其他规则适用于那里。请参见相关参数查找 - Bo Persson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接