[英]Why does friend function found successfully via ADL
考慮以下代碼:
#include <stdio.h>
class A
{
public:
friend void foo(A a){ printf("3\n"); }
};
int main()
{
foo(A());
}
有用。 但是我認為這段代碼無效。 這是因為3.4.1 / 3:
為了確定(在解析過程中)表達式是否為函數調用的后綴表達式,將應用通常的名稱查找規則 。
通常的名稱查找規則找不到朋友功能,因為在我的案例中,朋友聲明的名稱在全局命名空間中不可見。 實際上是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());
}
輸出將為42
因為3.4.1 / 3
為了確定(在解析過程中)表達式是否為函數調用的后綴表達式,將應用通常的名稱查找規則。
這意味着:為了確定foo
是后綴表達式(例如,強制轉換)還是函數調用,編譯器將首先使用名稱查找,並在全局名稱空間和/或將范圍/基類(或完全限定的類)中進行搜索。查找(如果有)。
現在使用以下代碼:
#include <iostream>
using namespace std;
class A
{
public:
friend int foo(A a){ return 55; }
operator int(){
return 42;
}
};
int main()
{
cout << foo(A());
}
借助ADL ,以上內容將輸出55
:通過在由其潛在參數(即A)定義的范圍內進行搜索,可以找到foo。
在您發布時,一個朋友聲明會引入一個(可能不可見)名稱(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
}
您可能要搜索“ 朋友姓名注入 ”和/或Barton-Nackman技巧 。 簡短的故事:現在,普通查找無法找到朋友聲明。
因此,您發布的代碼格式正確,因為ADL允許它按照我在前面的文章中解釋的那樣運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.