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
}