为什么找到f1但是f2没有?

时间:2015-09-28 03:14:40

标签: c++ friend-function

以下代码分为两个源文件。

首先:

namespace A {
    // two friends; neither is declared apart from a friend declaration
    // these functions implicitly are members of namespace A
    class C {
        friend void f2();           // won’t be found, unless otherwise declared
        friend void f1(const C&);   // found by argument-dependent lookup
    };
}
int main()
{
    A::C obj;
    f1(obj);        // ok: find A::f through the friend declaration in A::C
    A::f2();        // no member named f2 in namespace A
}

和第二个:

#include <iostream>
namespace A {
    class C;
    void f1(const C&) {
        std::cout << 1;
    }
    void f2() {
        std::cout << 2;
    }
}

第一段代码是从C ++入门复制而来的,唯一的区别是C ++引物调用 f2()没有前缀命名空间。第二部分是我的补充。我现在想知道 f1 f2 隐含地是命名空间A的成员,为什么 A :: f2()仍然是错误的 ADL可以找到f1(obj)吗?

2 个答案:

答案 0 :(得分:3)

这是7.3.1.2中的规则,导致A::f2()失败:

  

如果非本地类中的友元声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员。友元声明本身不会使名称对非限定查找(3.4.1)或限定查找(3.4.3)可见。

答案 1 :(得分:0)

在第一个代码块中,f2位于A::C的词法范围内,即该名称在A::C范围内可见。它在A::C之外不可见。

要使f2超出A::C的范围,您需要在A中声明或定义它。