[英]Ambiguous operator overload on clang
當我嘗試編譯這個測試程序時:
struct comma_guard
{
template<class T>
const comma_guard& operator,(T&&) const
{
return *this;
}
};
struct foo {};
template<class T> T operator,(T x, foo)
{
return x;
}
int main()
{
(comma_guard(), foo());
}
我在 clang 上收到編譯錯誤:
comma_guard.cpp:20:19: error: use of overloaded operator ',' is ambiguous (with operand types 'comma_guard' and 'foo')
(comma_guard(), foo());
~~~~~~~~~~~~~^ ~~~~~
comma_guard.cpp:6:24: note: candidate function [with T = foo]
const comma_guard& operator,(T&&) const
^
comma_guard.cpp:13:21: note: candidate function [with T = comma_guard]
template<class T> T operator,(T x, foo)
^
這在 gcc 上編譯得很好。 根據我對 ADL 查找的理解, comma_guard
的成員函數應該是首選的,因此不應有歧義。 這樣對嗎? 這是clang中的錯誤嗎? 另外,是否有一種解決方法,以便在comma_guard
中的運算符將始終是首選?
更新:因此,在模板化時,clang 似乎並不認為它是類成員。 因此,如果我像這樣定義comma_guard
,它將起作用:
struct comma_guard
{
struct any
{
template<class T>
any(T&&);
};
const comma_guard& operator,(any) const;
};
根據 C++ 哪個是正確的?
根據我對 ADL 查找的理解,comma_guard 中的成員函數應該是首選的,因此不應有歧義。 這樣對嗎?
回答:在重載解析期間,根據標准§ 13.3.1/2 & 7 Candidate functions and argument lists [over.match.funcs]:
2
候選函數集可以包含要針對同一參數列表解析的成員函數和非成員函數。
7
在候選函數模板的每種情況下,候選函數模板特化是使用模板參數推導生成的(14.8.3,14.8.2)。 然后以通常的方式將這些候選函數作為候選函數處理 [126]。[footnote
126
] 參數推導的過程完全決定了函數模板特化的參數類型,即函數模板特化的參數不包含模板參數類型。 因此,除非另有規定,函數模板特化和非模板函數 (8.3.5) 在重載解析的其余部分被同等對待。
因此,模板成員重載運算符在重載決議選擇方面沒有比模板自由重載運算符更高的優先級。
即使它有 GCC 選擇免費模板重載運算符LIVE DEMO 。
因此,以我的拙見,這里的 GCC 顯示了不符合標准的行為,而 Clang 理所當然地抱怨重載解析歧義。
另外,是否有一種解決方法,以便在comma_guard 中的運算符將始終是首選?
答案:是的,雖然有點丑: (comma_guard().operator,(foo()));
現場演示
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.