C++ 为什么通过ADL成功找到好友功能

C++ 为什么通过ADL成功找到好友功能,c++,friend,C++,Friend,考虑以下代码: #include <stdio.h> class A { public: friend void foo(A a){ printf("3\n"); } }; int main() { foo(A()); } #包括 甲级 { 公众: 朋友void foo(A){printf(“3\n”);} }; int main() { foo(A()); } 它起作用了。但是我认为这个代码是无效的。这是因为3.4.1/3: 用于确定(在解析期间)表达式

考虑以下代码:

#include <stdio.h>

class A
{
public:
    friend void foo(A a){ printf("3\n"); }
};

int main()
{ 
    foo(A());
}
#包括
甲级
{
公众:
朋友void foo(A){printf(“3\n”);}
};
int main()
{ 
foo(A());
}
它起作用了。但是我认为这个代码是无效的。这是因为3.4.1/3:

用于确定(在解析期间)表达式是否为 函数调用的后缀表达式,通常的名称查找规则 申请

通常的名称查找规则找不到friend函数,因为在本例中,friend声明的名称在全局命名空间中不可见。实际上3.3.1/4:

好友声明(11.3)可能会引入一个(可能不可见)名称 进入一个封闭的名称空间

这意味着程序的格式不正确。这是因为在确定表达式
foo(A())的过程中没有找到名称
是函数调用的后缀表达式


解析以下程序时,我弄糊涂了…

#include <iostream>
using namespace std;

typedef int foo;

class A
{
public:
   operator int(){
    return 42;
   }
};

int main()
{ 
    cout << foo(A());
}
上面将输出
55
,这要归功于:foo将通过在其潜在参数定义的范围内搜索来找到,即A

好友声明在您发布时引入了一个(可能不可见)名称(3.3.1/4)

好友声明(11.3)可能会引入一个(可能不可见)名称 进入一个封闭的名称空间

这意味着以下代码将不起作用

#include <iostream>
using namespace std;

class A
{
public:
   friend int foo(A a){ return 55; }

   operator int(){
    return 42;
   }
};

int main()
{ 
    cout << ::foo(A()); // Not found
    cout << A::foo(A()); // Not found
}
#包括
使用名称空间std;
甲级
{
公众:
friend int foo(A){return 55;}
运算符int(){
返回42;
}
};
int main()
{ 

你能在标题中找到答案吗?你到底在问什么?我会尽量弄清楚,我希望我是对的。如果不让我知道,我会编辑。@juanchopanza,因为foo在通常的名称查找中不可见。这意味着ADL不适用于foo(A()).@juanchopanza据我所知,ADL分层仅在常规名称查找后应用。但常规名称查找无法找到友元函数声明。在类体中定义的友元函数不在封闭类的范围内,它们在文件范围内。您不必问我的问题。对于常规名称查找,foo不可见。或claraify通常的名称查找是什么意思?@DmitryFucintv这是正常的名称查找(不是ADL):.Foo在没有ADL的情况下是找不到的,因为friend隐藏了作用域,您可以将其更像是一个子作用域。ADL的意思是=搜索参数作用域的所有子作用域。请仔细阅读解释
#include <iostream>
using namespace std;

class A
{
public:
   friend int foo(A a){ return 55; }

   operator int(){
    return 42;
   }
};

int main()
{ 
    cout << ::foo(A()); // Not found
    cout << A::foo(A()); // Not found
}