[問題] smart ptr 的operator 如何實作?

看板C_and_CPP (C/C++)作者 (小嫩)時間10年前 (2015/07/23 00:21), 10年前編輯推噓7(7055)
留言62則, 4人參與, 最新討論串1/1
代po, 請問如果自己實作smart pointer 又想支援類似 (sp->*pointer_to_member_function)(...); 我該怎麼實作 overloading ->*呢? 我試著用std shared_ptr 發現她沒有實作這 所以我必須要 sp.get()->* 或是用 (*sp).* 來使用, 但總覺得既然允許overload 不應該寫不出來呀 讓我很疑惑該怎麼辦? 所以請教各位 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 180.218.186.119 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1437582103.A.F65.html

07/23 00:38, , 1F
查了資料的結果是 ->* 就跟其他能 overload 的普通二元運算
07/23 00:38, 1F

07/23 00:38, , 2F
子一樣, 所以你可以回傳一個 proxy 物件在裡面做呼叫的動作
07/23 00:38, 2F

07/23 00:39, , 3F
可以貼一些程式碼嗎@@ 我還是不太清楚回傳啥比較正確
07/23 00:39, 3F

07/23 01:19, , 4F
https://ideone.com/yN3qGV 試寫了一下大概像這樣
07/23 01:19, 4F

07/23 02:49, , 5F
這份 code 有些最佳化空間 (eg.在 ->* 裡可以直接拉出
07/23 02:49, 5F

07/23 02:50, , 6F
raw pointer 丟進 Proxy 裡面), 不過概念應該有到
07/23 02:50, 6F

07/23 14:35, , 7F
thanks, LPH66..遇到兩個疑點
07/23 14:35, 7F

07/23 14:36, , 8F
如果function 是傳入pointer會出問題 會變成*&&
07/23 14:36, 8F

07/23 14:37, , 9F
另外我認為你實作的std::forward那地方的用意?
07/23 14:37, 9F

07/23 14:38, , 10F
Args&& 型態已經固定了 已經無法推導了阿
07/23 14:38, 10F

07/23 14:42, , 11F
所以就遇到 *變成 *&&的問題, 不過我想不到怎嚜改
07/23 14:42, 11F

07/23 17:55, , 12F
*&& 有甚麼問題?
07/23 17:55, 12F

07/23 19:41, , 13F
那邊的forward語意像是move吧?目前是把Arg&&...改成
07/23 19:41, 13F

07/23 19:41, , 14F
Arg... 不用rvalue ref來接 不然compile error
07/23 19:41, 14F

07/23 20:19, , 15F
誤會大了
07/23 20:19, 15F

07/23 20:25, , 16F
那個應該是universal reference(forward reference)?
07/23 20:25, 16F

07/24 02:58, , 17F
那就只是個用 rvalue ref 做 perfect forwarding 而已
07/24 02:58, 17F

07/25 01:39, , 18F
如果args&&是 int*&& compile error
07/25 01:39, 18F

07/25 01:46, , 19F
這邊型別已經固定是r value ref了沒有推導還能算是
07/25 01:46, 19F

07/25 01:46, , 20F
完美轉發嗎
07/25 01:46, 20F

07/25 06:23, , 21F
C++11 的 rvalue ref 有 reference collapsing rule
07/25 06:23, 21F

07/25 06:24, , 22F
如果 Args 是 lvalue ref 則會變成 & && 然後塌成 &
07/25 06:24, 22F

07/25 06:25, , 23F
所以當扔一個 lvalue ref 進去時那個參數其實是 lvalue ref
07/25 06:25, 23F

07/25 06:26, , 24F
詳情可看 #19gioP8j 這篇文章
07/25 06:26, 24F

07/25 10:24, , 25F
可是我丟int*進去 就沒collapse了阿 compile error
07/25 10:24, 25F

07/25 11:06, , 26F
可以的話給段 code 吧,應該哪裡有誤會
07/25 11:06, 26F

07/25 11:06, , 27F
至少給個錯誤訊息?
07/25 11:06, 27F

07/25 18:45, , 28F
加了第三個吃指標的函式進去 http://ideone.com/qZt3VX
07/25 18:45, 28F

07/25 18:46, , 29F
你再看一下你是不是哪裡弄錯了
07/25 18:46, 29F

07/25 23:14, , 30F
07/25 23:14, 30F

07/25 23:17, , 31F
int w; 改成 int *w; 就壞了, 老實講...這兩個型態
07/25 23:17, 31F

07/25 23:18, , 32F
有差嗎?
07/25 23:18, 32F

07/25 23:31, , 33F
有. 那這種 case 的話. 跟指標沒關. 你引數是左值就炸了
07/25 23:31, 33F

07/25 23:45, , 34F
我看了一下後我認同把 Args&& 改 Args
07/25 23:45, 34F

07/25 23:46, , 35F
確實是沒考慮到 overloading 的問題. 受教了.
07/25 23:46, 35F

07/25 23:50, , 36F
07/25 23:50, 36F

07/25 23:51, , 37F
可是我還是不懂差別耶 可以解釋一下嗎
07/25 23:51, 37F

07/25 23:53, , 38F
喔 我懂了@@也耍笨 thanks
07/25 23:53, 38F

07/26 06:48, , 39F
啊, 我搞錯 perfect forwarding 的寫法了...
07/26 06:48, 39F

07/26 06:49, , 40F
perfect forwarding 需要函數參數的型別在函數自己的模版裡
07/26 06:49, 40F

07/26 06:50, , 41F
這樣才能觸發 rvalue ref 的特殊模版推導規則
07/26 06:50, 41F

07/26 06:51, , 42F
所以把 Proxy 的 operator() 加個模版就行了
07/26 06:51, 42F

07/26 06:51, , 43F
變成像是這樣 http://ideone.com/ZBnLhn
07/26 06:51, 43F

07/26 06:51, , 44F
呼叫方也改成有丟左值跟丟右值的狀況以資證明這是 OK 的
07/26 06:51, 44F

07/26 06:53, , 45F
這個特殊推導規則是: 模版型別若在函式參數裡是 rvalue ref
07/26 06:53, 45F

07/26 06:54, , 46F
的型式出現時, 推導結果視乎呼叫方該參數是左值還右值而定
07/26 06:54, 46F

07/26 06:54, , 47F
左值則推導為 lvalue ref, 右值則推導為不帶 ref 的型態
07/26 06:54, 47F

07/26 06:55, , 48F
這只在函式模版才有, class 模版不會也無法做這種推導
07/26 06:55, 48F

07/26 13:05, , 49F
可是這樣改 導致外部想call by value莫名變成by ref
07/26 13:05, 49F

07/26 13:05, , 50F
了 不是嗎?以l value 傳進去來講
07/26 13:05, 50F

07/26 14:14, , 51F
這裡的問題在於 function call 的參數型態已經由函式指標
07/26 14:14, 51F

07/26 14:14, , 52F
決定了.
07/26 14:14, 52F

07/26 14:15, , 53F
所以不管你傳甚麼他都會試著轉成可以函式指標參數的型態
07/26 14:15, 53F

07/26 14:15, , 54F
所以不管你要改成 Args 或加上 ActualArgs 都可以
07/26 14:15, 54F

07/26 14:17, , 55F
但是 forward 的存在是必要的
07/26 14:17, 55F

07/26 15:43, , 56F
喔喔 傳lvalue看來他遲早會做一次copy 不管是args
07/26 15:43, 56F

07/26 15:43, , 57F
先copy 還是actualarg 之後再copy
07/26 15:43, 57F

07/26 15:57, , 58F
Args 跟 ActualArgs 的差別是推導的依據是函式指標的參數型
07/26 15:57, 58F

07/26 15:58, , 59F
態或者是呼叫的引數型態. copy 都是在同一個地方發生
07/26 15:58, 59F

07/26 15:58, , 60F
(如果合法的話)
07/26 15:58, 60F

07/26 16:08, , 61F
阿. 我懂你意思. 是都在 operator() 但是時機不同. 我誤會了
07/26 16:08, 61F

07/26 16:09, , 62F
最近語言理解能力有點問題啊啊啊.
07/26 16:09, 62F
※ 編輯: dreamboat66 (180.218.186.119), 08/04/2015 22:53:38
文章代碼(AID): #1LhyCNzb (C_and_CPP)
文章代碼(AID): #1LhyCNzb (C_and_CPP)