[英]C++ conversion operator and overload resolution
鑒於此示例,其中包含一些重載:
#include <iostream>
class T
{
public:
operator const wchar_t *(void) const
{
std::cout << "Conversion" << std::endl;
return L"Testing";
}
};
template <class Elem>
class A
{
};
template <class T>
void operator <<(A<T> &, const T *)
{
std::cout << "1" << std::endl;
}
template <class T>
void operator <<(A<T> &, const void *)
{
std::cout << "2" << std::endl;
}
int main(void)
{
A<wchar_t> test;
T source;
test << L"1";
test << static_cast<const wchar_t *>(source);
test << source;
}
它的輸出:
1
Conversion
1
Conversion
2
我的問題是 - 為什么要為語句test << source;
調用void operator <<(A<T> &, const void *)
test << source;
? 任何人都可以引用涵蓋此案例的標准的特定部分嗎?
因為模板參數推導不會考慮用戶定義的隱式轉換。 結果就是當你寫道:
test << source;
,編譯器無法為第一個函數模板找到合適的T
; 它試圖找到一個T
,使得T const*
與你的T
具有相同的類型,這是不可能的。 參數推斷失敗,並且沒有將模板的實例化添加到重載集。 由於第二個函數模板的第二個參數中沒有模板參數,因此沒有參數推斷失敗,並且生成的實例化成為重載集的唯一成員,因此最終被選中。
它使用T
的隱式轉換為wchar_t
。 任何類型都可以轉換為void*
因此編譯器會調用該operator<<
版本。 T*
運算符從來都不是候選者,因為無法從T
隱式獲得T*
。 你的意思是讓它成為T&
<<
運營商嗎?
模板參數的隱式推導不會考慮用戶定義的隱式轉換。 因此,調用template <class T> void operator <<(A<T> &, const T *)
會將T
從第一個參數推導為wchar_t
,但第二個參數是T
而不是const wchar_t*
。 因此編譯器將無法匹配該運算符。
對於template <class T> void operator <<(A<T> &, const void *)
,問題看起來不同: T
將從第一個函數參數推斷為wchar_t
。 第二個參數可以通過用戶定義的轉換隱式轉換為const wchar_t*
,然后可以通過轉換構建將其隱式轉換為const void*
。 因此,此函數可以使用這些參數調用並使用,因為無法推導出另一個函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.