对参数依赖查找和友元函数定义的困惑

时间:2014-09-16 16:54:27

标签: c++ c++11 language-lawyer argument-dependent-lookup

我有以下程序:

struct Foo {
    friend void foo (int) {}
    operator int () const { return 0; }
};

int main() {
    foo(Foo());  // This compiles fine
    foo(0);      // This fails to find `foo()`
    return 0;
}

我无法弄清楚标准的哪个部分定义了ADL规则,该规则表示对foo(0)的调用失败,而对foo(Foo())的调用应该成功。有人可以解释一下吗?

2 个答案:

答案 0 :(得分:1)

重新打开我自己的删除,是吗?好吧,经过juanchopanza的一些提示后,我更仔细地阅读了标准的相关部分C ++11§3.4.2。我以前浏览得太快了。也就是说,第2段阐明:

  

对于函数调用中的每个参数类型T,都有一组零个或多个关联的命名空间以及一组零个或多个要考虑的关联类。命名空间和类的集合完全由函数参数的类型(以及任何模板模板参数的命名空间)决定。用于指定类型的Typedef名称和 using-declarations 对此集合没有贡献。命名空间和类的集合按以下方式确定:

     
      
  • 如果T是基本类型,则其关联的命名空间和类集都是空的。
  •   
  • 如果T是类类型(包括联合),则其关联的类是:类本身;它所属的成员,如果有的话;及其直接和间接基类。其关联的名称空间是其关联类是成员的名称空间。此外,如果T是类模板特化,则其关联的名称空间和类还包括:与模板类型参数(模板模板参数除外)提供的模板参数类型相关联的名称空间和类;任何模板模板参数都是成员的名称空间;以及用作模板模板参数的任何成员模板的类都是成员。
  •   
     

...

第一个子弹解释了为什么传入int参数失败。第二个项目解释了传递Foo实例的原因。

答案 1 :(得分:0)

查看您的代码:

int main() {
    foo(Foo());  // This declares a global function "foo" taking a "Foo" as an argument
    foo(0);      // "foo" takes a "Foo" above, and theres no way to convert an int to a Foo...