混沌 IN C++::轉換函式
難度:
問題:
下面這段程式碼為什麼會編譯失敗呢?
struct T
{
operator std::string() const
{
return std::string();
}
operator int() const
{
return int();
}
};
int main()
{
T t;
int i = t;
std::string s = t;
i == t; //成功
s == t; //失敗
}
回答:
因為標準庫沒有提供bool operator==(const std::string&, const std::string&);這樣的過載,而是提供了
template<typename CharT, typename Traits, typename Alloc>
bool operator==(const std::basic_string<CharT, Traits, Alloc>&, const std::basic_string<CharT, Traits, Alloc>&);
當s == t 進行比較的時候,編譯器用第一個引數s可以推匯出CharT, Traits, Alloc這三個模板引數,然後用t來推導,結果是無法完成推導,因為t並不是basic_string<>。那T中的operator std::string() const的轉換函式在這裡有什麼作用呢?事實上,這個轉換函式在這裡一點用也沒有,C++沒有提供一個規則是先轉換再推導函式模板引數的。解決這個問題的辦法,就是讓編譯器在推導第二個引數的型別之前,顯式地將t轉換為std::string。
s == std::string(t);
到這一步,有人又會納悶,basic_string也沒提供basic_string(const std::string&)的建構函式啊,而是提供的
template<typename CharT, typename Traits, typename Alloc>
basic_string(const basic_string<CharT, Traits, Alloc>&);
按照上面的說法,那顯式轉換std::string(t)是怎麼完成推導函式模板引數的呢? 其實std::string並不是類别範本了,而是被例項化成basic_string<char>這個模板類,std::string(t)也沒有進行推導,因為已經明確了CharT, Traits, Alloc這三個模板引數,所以這時的operator std::string() const起作用了。
相關文章
- c++ operator typename 轉換函式C++函式
- C++型別轉換建構函式C++型別函式
- 轉換函式函式
- C++型別轉換時定義非成員函式(轉)C++型別函式
- numtoyminterval函式——數字轉換函式函式
- C++的函式和模板函式 (轉)C++函式
- 【C++】禁止隱式轉換C++
- 類的轉換函式函式
- php轉換ip函式PHP函式
- js日期轉換函式JS函式
- 函式式 Java 到函式式 Kotlin 的轉換函式JavaKotlin
- oracle 10g函式大全--轉換函式Oracle 10g函式
- 函式組:TRUX 包含很多的轉換函式函式UX
- Oracle OCP(05):轉換函式Oracle函式
- 8.轉換文字函式函式
- 索引ROWID轉換函式索引函式
- ORACLE單行函式與多行函式之五:轉換函式示例Oracle函式
- C++隱式類型別轉換C++型別
- C++隱式型別的轉換C++型別
- C++ 隱式類型別轉換C++型別
- 轉換時間戳的函式時間戳函式
- oracle 全形半形轉換函式Oracle函式
- 日期轉換為raw的函式函式
- string大小寫轉換函式函式
- SQL 數字轉換英文函式SQL函式
- C++虛擬函式解析(轉載)C++函式
- C++中的虛擬函式與虛擬函式表 (轉)C++函式
- mysql和oracle字串編碼轉換函式,字串轉位元組函式例子MySqlOracle字串編碼函式
- C++ 表示式中的型別轉換C++型別
- C++函式C++函式
- 【C++】函式C++函式
- oracle內部轉換函式雜談Oracle函式
- GBK中文繁簡轉換函式函式
- MySQL字串函式 字串大小寫轉換MySql字串函式
- Base64與BLOB 轉換函式函式
- 浮點數轉換成字串函式字串函式
- oracle時間間隔轉換函式Oracle函式
- oracle中進位制轉換函式Oracle函式