[英]Overload resolution for operator functions
為什么這段代碼不能編譯? 我本以為會選擇內置的一元運算符 &,這樣兩個二元運算符 & 之間的歧義就不重要了。 如果注釋掉其中一個二元運算符 &,代碼將編譯(使用 gcc 11.2)並選擇內置的一元運算符 &。
struct A
{ int operator&(int) const { return 1; }
};
struct B
{ int operator&(int) const { return 2; }
};
struct C : A, B
{};
C* test(C& c)
{ return &c; } //error: request for member 'operator&' is ambiguous
問題是過載解析。 第一個 function 名稱應該匹配,如果發現鄰接應該報告錯誤。 之后執行 arguments 的匹配。 這是常規 function 的示例: https://godbolt.org/z/nYfjdn1Td
正如您所看到的,即使兩個foo
的 arguments 數量不同,所有編譯器都會報告foo
的歧義。
operator&
應該會彈出同樣的問題,所以更像是 gcc 就在這里。
過載解決方案是一個復雜的話題。 通常你不必考慮它。 這是很好的資源,它解釋了這是多么復雜。
如果您希望解決問題並為此類代碼提供二元運算符,您可以這樣做:
struct C : A, B
{
using A::operator&;
using B::operator&;
};
這解決了您在所有編譯器上的測試問題。
當然, instaceOfC & intValue
的歧義仍然存在,但您可以通過添加一個using
語句來解決它。
這是由於 不合格的名稱查找。
最初,名稱查找從 class C 的C
。 未找到operator&
的聲明。
然后查找依次進行到基類。 在A
和B
中的每一個中,都有一個名為operator&
的不同聲明。
此時通過名稱查找找到的聲明集是A::operator&
和B::operator&
。 這些在名稱查找階段被認為是模棱兩可的,因此永遠不會達到重載解析,在該階段會發現一元和二元operator&
之間的差異。
有關更多信息,請參閱 cppreference 上的示例以查找不合格的名稱。
如果只有A
或B
中的一個被繼承,則名稱查找集不會是成員 function 名稱查找集不會有歧義。 它將繼續重載解析並正確推斷出一元運算operator&
。
在 class C
的主體中添加一個using
聲明,將它們都帶入 scope C::
進行名稱查找。 .
struct C : A, B
{
using A::operator&;
using B::operator&;
};
在基類之前搜索C 的C
,因此永遠不會達到不明確的步驟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.