簡體   English   中英

運算符函數的重載解析

[英]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語句來解決它。

https://godbolt.org/z/ds3W4GYcT

這是由於 不合格的名稱查找

最初,名稱查找從 class C 的C 未找到operator&的聲明。

然后查找依次進行到基類 AB中的每一個中,都有一個名為operator&的不同聲明。

此時通過名稱查找找到的聲明集是A::operator&B::operator& 這些在名稱查找階段被認為是模棱兩可的,因此永遠不會達到重載解析,在該階段會發現一元和二元operator&之間的差異。

有關更多信息,請參閱 cppreference 上的示例以查找不合格的名稱。

如果只有AB中的一個被繼承,則名稱查找集不會是成員 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM