看看下面這個例子:
1 template2class
rational;
8 template9
const rationaloperator*(const rational&lhs,
10const rational&rhs);
11 rational onehalf(1,2
);12 rational result = onehalf*2;
上面的最後乙個式子看起來好像能夠通過編譯,但是實際上不能,因為模版的關係,編譯器不會知道我們想呼叫的是哪個函式。
上面式子能推倒出來,正確的可能就是編譯器使用rational的non-explicit建構函式將2轉換,但是編譯器進行實參推倒的時候不會將隱式轉換放到考慮的範圍裡面。
而解決上述問題的有效方法就是,不要讓operator*需要去進行引數的推倒,而是將其設為rational的乙個friend函式:
1 template2class
rational;
這樣,當onehalf宣告出來的時候,就相當於自動宣告出來了上面的operator*,這樣的隱式轉換同樣也來能夠成功。
在乙個class template裡面,template名稱可以被用來當作「template何其引數的建議表達形式」,所以說上面的形式和下面的
1friend
2const rationaloperator*(const rational&lhs,
3const rational& rhs);
constrational&rhs);
實際上是相同的。
但實際上上面咋rational外部去給operator*乙個定義是行不通的,因為模板的原因,這個定義必須被放置在類的內部,就像下面這樣:
1 template2class
rational
14 };
這裡的使用friend實際上有其獨到的意義:為了讓型別轉換可以發生在所有的實參身上,需要乙個non-member,為了讓這個函式被自動具體化,我們需要將他們宣告在class內部,而在class內部宣告non-member函式的唯一方法就是將他宣告稱friend。!!
小結:當編寫乙個class template的時候,起所提供的「與此template相關的」函式支援「所含引數的隱式型別」時,應該將那些函式定義為「class template 內部的」friend函式
。
條款46 需要型別轉換時請為模板定義非成員函式
條款46 需要型別轉換時請為模板定義非成員函式 define non member functions inside templates when type conversion are desired.還記得在條款24中,我們提到只有non member函式才有能力 在所有實參身上實施隱式型別轉換...
C 需要型別轉換時請為模板定義非成員函式
20180403 c 需要型別轉換時請為模板定義非成員函式 只有非成員函式才有能力 在所有實參身上實施隱式型別轉換 該條款可以通過rational 有理數 類和operator 函式為例證明。本文將擴充這一條款 將rational類和operator 函式模板化 template class rat...
需要型別轉換時定義為非成員函式
所以為了看我文章的人不會遭遇同樣的問題,2.盡可能循序漸進 還是看不懂可能是我沒有這樣的天賦 標出閱讀的前提知識 3.列出的 自己先跑一遍 c 1.類 2.函式過載 3.型別轉換 整合開發環境 visual studio 2017 class num 不設explicit,提供隱式轉換 constn...