[問題] 限制 Template 的具現化

看板C_and_CPP (C/C++)作者 (夜殘狼)時間14年前 (2012/04/29 00:00), 編輯推噓1(1052)
留言53則, 3人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) NO 問題(Question): 最近剛初學 Template 在寫繼承的時候遇到一個問題 假設 Base class A_base 有如下的運算子重載 friend A_base operator+(const A_base &lhs,const A_base &rhs) { ... return Temp_A_base; } 另有 Derived class A_derived:public A_base{...} 我希望可以不用重寫一個重載函式(因為實際上內容完全相同)如下 friend A_derived operator+(const A_derived &lhs,const A_derived &rhs) { ... return Temp_A_derived; } 所以我嘗試用 Template 來簡化 程式碼如下 template<typename T> inline T operator+( const T &lhsob, const T &rhsob ) { ... return static_cast<T>( Temp_result ); } 然後在 class 內放 friend A_derived operator+ <A_derived> ( const A_derived& , const A_derived& ); 經測試可以運作無誤 但問題來了 我在想,這樣的寫法會不會讓引用我頭檔的使用者 寫下不是我所寫的型別的加法時不小心被我這個 Template 具現化,以致結果出錯呢? 例如他寫下 B_type a,b; a + b; A_derived c,d; c + d; 然後就出錯這樣 為了解決這個問題 想請問一下 有沒有辦法指定他只能具現化特定型別的函數呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.47.222.76 ※ 編輯: birdhackor 來自: 114.47.222.76 (04/29 00:06)

04/29 01:41, , 1F
內容為什麼會一樣呢?
04/29 01:41, 1F

04/29 08:02, , 2F
virtual friend function可解??
04/29 08:02, 2F

04/29 08:04, , 3F
因為它只是把一個成員變數相加而已
04/29 08:04, 3F

04/29 08:25, , 4F
virtual friend function 可以達成回傳derived class
04/29 08:25, 4F

04/29 08:26, , 5F
的效果嗎?
04/29 08:26, 5F

04/29 08:32, , 6F
不行,可是回傳值很不一般。
04/29 08:32, 6F

04/29 09:24, , 7F
那還是沒辦法解決說...因為我的目的是讓他傳回
04/29 09:24, 7F

04/29 09:24, , 8F
derived class object
04/29 09:24, 8F
順便問個問題,照理來說應該有很多函示庫有定義到 像是 template<typename T> inline T operator+( const T &lhsob, const T &rhsob ) 這樣的template 為甚麼具現化的時候不會出錯呢? ※ 編輯: birdhackor 來自: 114.47.222.76 (04/29 09:26)

04/29 15:02, , 9F
該成員變數是從basse class繼承來的, 所以一樣?
04/29 15:02, 9F

04/29 15:45, , 10F
04/29 15:45, 10F

04/29 17:30, , 11F
你case的是duplicate codes, 這改一下設計就好了, 利
04/29 17:30, 11F

04/29 17:31, , 12F
用is a關係復用程式碼, 再透過轉呼叫運算子去掉friend
04/29 17:31, 12F

04/29 17:32, , 13F
這種雙向相依的程式碼 http://codepad.org/q2K2f6zk
04/29 17:32, 13F

04/29 17:41, , 14F
如果本來的 code 可以 work, 你應該重複思考一下為什
04/29 17:41, 14F

04/29 17:42, , 15F
麼子類別可以存取父類別的資料成員? 有這個必要嗎?
04/29 17:42, 15F

04/29 17:42, , 16F
如果有, 那有必要寫成兩個類別嗎?
04/29 17:42, 16F

04/29 17:49, , 17F
我寫的是矩陣運算 Base class 是廣義矩陣
04/29 17:49, 17F

04/29 17:50, , 18F
在廣義矩陣上,定義方陣與行列向量這三個Derived class
04/29 17:50, 18F

04/29 17:51, , 19F
矩陣加減乘法是完全相同的 但方陣額外有 trace det
04/29 17:51, 19F

04/29 17:52, , 20F
diagonal 等方法是廣義矩陣沒有的
04/29 17:52, 20F

04/29 17:52, , 21F
行列向量則是有長度運算是其他沒有的
04/29 17:52, 21F

04/29 18:04, , 22F
ok
04/29 18:04, 22F

04/29 18:06, , 23F
繼承的技術我沒啥問題...寫法很多...我只是想知道能不
04/29 18:06, 23F

04/29 18:06, , 24F
不能用 template 來偷懶...
04/29 18:06, 24F

04/29 18:08, , 25F
問題是根本沒有東西可以給你偷懶阿... 硬是要開大門
04/29 18:08, 25F

04/29 18:09, , 26F
就只能用 yoco 大的方式再把不想走的關起來
04/29 18:09, 26F

04/29 18:11, , 27F
一開始 "內容完全相同" 這點你就該注意到寫法是有問題
04/29 18:11, 27F

04/29 18:12, , 28F
的, 然後又要用 template 來影響其他沒關係的類別,
04/29 18:12, 28F

04/29 18:13, , 29F
現在 work 了, 之後也會有問題的
04/29 18:13, 29F

04/29 18:16, , 30F
請問內容完全相同這點哪裡有問題? 他們的操作一樣所以
04/29 18:16, 30F

04/29 18:17, , 31F
寫出來就一樣阿...
04/29 18:17, 31F

04/29 18:28, , 32F
內容相同表示他們在做同樣的事情, 操作一樣, 存取的成
04/29 18:28, 32F

04/29 18:28, , 33F
員都是從父類別繼承來的, 表示這個 method 應該只存在
04/29 18:28, 33F

04/29 18:29, , 34F
於父類別, 你這是為了讓子類別也能擁有一樣的 + 操作
04/29 18:29, 34F

04/29 18:30, , 35F
但是忽略了參數用 & 傳遞的涵義: 可以透過 is a 關係
04/29 18:30, 35F

04/29 18:31, , 36F
叫用父類別的版本, 所以不需要為了best match來多複製
04/29 18:31, 36F

04/29 18:31, , 37F
相同程式碼, 你只需要考慮回傳時會不會被 slice 掉
04/29 18:31, 37F

04/29 18:38, , 38F
你應該要仔細思考operator+ 的signature究竟差別在哪
04/29 18:38, 38F

04/29 18:38, , 39F
我不是為了best match才去複製...
04/29 18:38, 39F

04/29 18:40, , 40F
我的想法是,既然是用&傳遞,就可以直接用動態定型
04/29 18:40, 40F

04/29 18:40, , 41F
使用父類別已經宣告好的operator+
04/29 18:40, 41F

04/29 18:40, , 42F
存取父類別的成員, 不需要透過子類別 reference
04/29 18:40, 42F

04/29 18:42, , 43F
A_base operator+(const A_base &lhs,const A_base &rh
04/29 18:42, 43F

04/29 18:43, , 44F
的寫法後面雖然動態型別仍為子類別,回傳卻會被傳成
04/29 18:43, 44F

04/29 18:43, , 45F
父類別,但我希望他回傳的是子類別
04/29 18:43, 45F

04/29 18:44, , 46F
但我又不想宣告兩個像是 Base operator+( Base const &
04/29 18:44, 46F

04/29 18:45, , 47F
Derived operator+( Derived const &lhs....
04/29 18:45, 47F

04/29 18:45, , 48F
這樣子,實際上只有型別上有差的overload
04/29 18:45, 48F

04/29 18:46, , 49F
所以才把腦筋動到template上
04/29 18:46, 49F

04/29 20:54, , 50F
所以重點其實是在 signature 的 adapt 而不是用模板來
04/29 20:54, 50F

04/29 20:55, , 51F
作 codegen
04/29 20:55, 51F

04/29 21:02, , 52F
用了模板你把它合成一份程式碼, 但是卻產生了更多不必
04/29 21:02, 52F

04/29 21:03, , 53F
要的程式碼
04/29 21:03, 53F
文章代碼(AID): #1Fd1GQpS (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1Fd1GQpS (C_and_CPP)