【46】需要型別轉換時請為模版定義非成員函式

Andy Niu發表於2014-01-23

1、假設【24】中的Rational是類模版,同時有non-member的方法模版,現在考慮下面的呼叫:

  Rational<int> a(1,2);

  Rational<int> result = a*2; // Error

2、為什麼?

  呼叫方法的時候,如果沒有完全匹配的方法,編譯器會嘗試進行隱式型別轉換。現在考慮模版的例項化,呼叫方法的時候,編譯器根據模版實參,確定模版形參,然後例項化一個方法。但是,例項化方法的時候,從不進行隱式型別轉換。思考為什麼?假如考慮隱式型別轉換,那麼存在隱式型別轉換的情況多了,不可能都去例項化。也就是說,模版例項化的時候,不考慮隱式型別轉換,因此也就沒有例項化方法。沒有生成方法,後面的方法呼叫當然有問題。

3、怎麼解決呢?

  模版例項化不考慮隱式型別轉換,那麼我們就要想辦法,讓它例項化一個方法出來。做法是:在類模版中宣告一個friend方法。這樣的話,當例項化類的時候,也就例項化一個non-member方法了。

4、特別注意:這裡friend目的不是為了訪問private成員。而是因為,要在類中宣告方法,只能宣告friend方法。

5、在類模版定義中的friend方法,如果提供實現,意味著申請成為inline方法。如果方法實現複雜,可以在外部實現,或者在外部定義一個輔助方法,在類定義中令friend方法呼叫輔助方法。

相關文章