代码之家  ›  专栏  ›  技术社区  ›  jxh

对依赖于参数的查找和友元函数定义的混淆

  •  0
  • jxh  · 技术社区  · 10 年前

    我有以下计划:

    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 回复  |  直到 10 年前
        1
  •  1
  •   jxh    10 年前

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

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

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

    ...

    第一颗子弹解释了为什么 int 参数失败。第二颗子弹解释了为什么在 Foo 实例工作。

        2
  •  0
  •   Chris Dodd    10 年前

    查看代码:

    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...