如何调用与成员函数同名的内联好友函数?

时间:2014-06-11 16:24:45

标签: c++ friend overload-resolution argument-dependent-lookup

如此处所述C++11 style SFINAE and function visibility on template instantiation类成员函数掩盖了自由函数。使用完全限定的名称通常有效,但是我很难与其他类的朋友函数一起使用,这些函数是在线声明的。请考虑以下示例:

namespace N {

    struct C {
        friend int f(const C& c) {
            return 1;
        }
        friend int g(const C& c) {
            return 2;
        }
    };

    struct D {
        void f() {
            g(C{});            // ADL finds this
            ::N::f(C{});       // not found dispite full qualification
        }
    };
}

我想我明白了问题所在,正如这里所描述的What's the scope of inline friend functions?内联友元函数通常是使用ADL找到的,并且在封闭的命名空间中并不真正可见。

所以我的问题是我应该如何更改我的代码以使其工作(除了重命名其中一个f)?

1 个答案:

答案 0 :(得分:3)

这是因为friend liness:

  

[C++11: 7.3.1.2/3]:如果非本地类中的朋友声明首先声明一个类或函数,那么友元类或函数是最内层封闭命名空间的成员。 在该命名空间范围 [...] 中提供匹配声明之前,通过简单名称查找找不到该朋友的姓名。如果调用了友元函数,则可以通过名称查找找到其名称,该名称查找考虑来自名称空间的函数和与函数参数的类型相关联的类(3.4.2) [即。 ADL]

解决方法是简单地提供声明:

namespace N {

    struct C {
        friend int f(const C& c) {
            return 1;
        }
        friend int g(const C& c) {
            return 2;
        }
    };

    int f(const C& c);
    int g(const C& c);

    struct D {
        void f() {
            g(C{});
            ::N::f(C{});
        }
    };
}

live demo