混沌 IN C++::轉換函式

jinhao發表於2008-09-08

難度:

問題:

    下面這段程式碼為什麼會編譯失敗呢?

 

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起作用了。

相關文章