C 需要型別轉換時請為模板定義非成員函式

2021-08-18 21:04:10 字數 1287 閱讀 9694

20180403 c++ 需要型別轉換時請為模板定義非成員函式

只有非成員函式才有能力「在所有實參身上實施隱式型別轉換」,該條款可以通過rational(有理數)類和operator*函式為例證明。本文將擴充這一條款:將rational類和operator*函式模板化:

template

class rational

;template

const rationaloperator*(const rational& lhs,

const rational& rhs)

我們希望支援混合式算數運算,即:

rationalonehalf(1,2);

rationalresult = onehalf * 2;//錯誤,無法通過編譯。

上述失敗給我們的啟示是,模板化的rational裡的某些東西似乎和他的非模板版本不同,在這裡編譯器不知道我們想要呼叫哪個函式。取而代之的是它們試圖想出什麼函式被命名為operator*的模板具現化(產生)出來。它們知道它們可以具現化某個「名為operator*並接受兩個rational引數」的函式。但為完成這一具現化行為,必須先算出t是什麼,問題的它沒有這個能耐。

只要利用乙個事實,我們就可以緩和編譯器在模板引數推導方面受到的挑戰:模板類裡的友元宣告式可以指涉某個特定函式。那意味著類 rational可以宣告operator*是它的乙個友元函式。類模板並不依賴模板實參推導(後者只施行於函式模板身上),所以編譯器總是能夠在類rational具現化時得知t,因此令rational類宣告適當的operator*為其友元函式,可簡化整個問題:

template

class rational

;template

const rationaloperator*(const rational& lhs,//定義operator*函式

const rational& rhs)

現在對operator*的混合呼叫可以通過編譯了,

我們可以將operator*函式本體合併至其宣告式中:

template

class rational

}這項技術的特點是,我們雖然使用友元,卻與友元的傳統用途「訪問類的非公有成分」毫不相干。為了讓轉型可能發生於所有實參身上,我們需要乙個非成員函式;為了讓型別轉換可能發生於所有實參身上,我們需要乙個非成員函式;為了讓這個函式被自動具現化,我們需要將他宣告在類內部,而在類裡宣告非成員函式的唯一辦法就是:令他成為乙個友元,因此我們就這樣做了。

注意:當我們編寫乙個類模板時,而他所提供的「與此模板相關的」函式支援「所有引數的隱式型別轉換」的時候,請將那些函式定義為「類模板內部的友元函式」。

條款46 需要型別轉換的時候請為模板定義非成員函式

看看下面這個例子 1 template2 class rational 8 template9 const rationaloperator const rational lhs,10const rational rhs 11 rational onehalf 1,2 12 rational res...

條款46 需要型別轉換時請為模板定義非成員函式

條款46 需要型別轉換時請為模板定義非成員函式 define non member functions inside templates when type conversion are desired.還記得在條款24中,我們提到只有non member函式才有能力 在所有實參身上實施隱式型別轉換...

需要型別轉換時定義為非成員函式

所以為了看我文章的人不會遭遇同樣的問題,2.盡可能循序漸進 還是看不懂可能是我沒有這樣的天賦 標出閱讀的前提知識 3.列出的 自己先跑一遍 c 1.類 2.函式過載 3.型別轉換 整合開發環境 visual studio 2017 class num 不設explicit,提供隱式轉換 constn...