【问题标题】:Why f1 is found but f2 not?为什么找到 f1 而没有找到 f2?
【发布时间】:2015-09-28 03:14:39
【问题描述】:

以下代码位于两个源文件中。

第一:

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++ Primer 复制而来,唯一的区别是 C++ Primer 调用 f2() 没有前缀命名空间。第二件是我的补充。我现在想知道 f1f2 隐含地是命名空间 A 的成员,为什么 A::f2() 仍然错误而 f1(obj) 可以被 ADL 找到吗?

【问题讨论】:

  • 我第一次遇到 ADL……我的反应大概是“OHMYGODWHY”。
  • @Cubic 以便 std::cout &lt;&lt; 'x'; 工作。如果没有 ADL,您将不得不编写 using std::operator&lt;&lt;std::operator&lt;&lt;(std::cout, 'x'); 等。

标签: c++ friend-function


【解决方案1】:

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

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

【讨论】:

  • 我仍然很困惑,为什么 ADL 找到了 f1 而没有找到 f2?它们之间有什么区别吗?或者,从你摘录的最后一句,仅仅因为 f1 被 ADL 找到了?
  • @xlnwel:是的,ADL 规则允许查找无法通过名称找到的内容。
【解决方案2】:

在第一个代码块中,f2A::C 的词法范围内,即名称在A::C 的范围内可见。在A::C之外是不可见的。

要使f2A::C 范围之外可见,您需要在A 中声明或定义它。

【讨论】:

  • f1 被 ADL 发现。由于f2 没有任何参数,因此无法使用ADL 查找f2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2018-05-11
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多