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方法呼叫輔助方法。