看板 C_and_CPP 關於我們 聯絡資訊
代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
LPH66: 查了資料的結果是 ->* 就跟其他能 overload 的普通二元運算 07/23 00:38
LPH66: 子一樣, 所以你可以回傳一個 proxy 物件在裡面做呼叫的動作 07/23 00:38
dreamboat66: 可以貼一些程式碼嗎@@ 我還是不太清楚回傳啥比較正確 07/23 00:39
LPH66: https://ideone.com/yN3qGV 試寫了一下大概像這樣 07/23 01:19
LPH66: 這份 code 有些最佳化空間 (eg.在 ->* 裡可以直接拉出 07/23 02:49
LPH66: raw pointer 丟進 Proxy 裡面), 不過概念應該有到 07/23 02:50
dreamboat66: thanks, LPH66..遇到兩個疑點 07/23 14:35
dreamboat66: 如果function 是傳入pointer會出問題 會變成*&& 07/23 14:36
dreamboat66: 另外我認為你實作的std::forward那地方的用意? 07/23 14:37
dreamboat66: Args&& 型態已經固定了 已經無法推導了阿 07/23 14:38
dreamboat66: 所以就遇到 *變成 *&&的問題, 不過我想不到怎嚜改 07/23 14:42
Feis: *&& 有甚麼問題? 07/23 17:55
dreamboat66: 那邊的forward語意像是move吧?目前是把Arg&&...改成 07/23 19:41
dreamboat66: Arg... 不用rvalue ref來接 不然compile error 07/23 19:41
Feis: 誤會大了 07/23 20:19
BlazarArc: 那個應該是universal reference(forward reference)? 07/23 20:25
LPH66: 那就只是個用 rvalue ref 做 perfect forwarding 而已 07/24 02:58
dreamboat66: 如果args&&是 int*&& compile error 07/25 01:39
dreamboat66: 這邊型別已經固定是r value ref了沒有推導還能算是 07/25 01:46
dreamboat66: 完美轉發嗎 07/25 01:46
LPH66: C++11 的 rvalue ref 有 reference collapsing rule 07/25 06:23
LPH66: 如果 Args 是 lvalue ref 則會變成 & && 然後塌成 & 07/25 06:24
LPH66: 所以當扔一個 lvalue ref 進去時那個參數其實是 lvalue ref 07/25 06:25
LPH66: 詳情可看 #19gioP8j 這篇文章 07/25 06:26
dreamboat66: 可是我丟int*進去 就沒collapse了阿 compile error 07/25 10:24
Feis: 可以的話給段 code 吧,應該哪裡有誤會 07/25 11:06
Feis: 至少給個錯誤訊息? 07/25 11:06
LPH66: 加了第三個吃指標的函式進去 http://ideone.com/qZt3VX 07/25 18:45
LPH66: 你再看一下你是不是哪裡弄錯了 07/25 18:46
dreamboat66: http://ideone.com/HBKoCW 07/25 23:14
dreamboat66: int w; 改成 int *w; 就壞了, 老實講...這兩個型態 07/25 23:17
dreamboat66: 有差嗎? 07/25 23:18
Feis: 有. 那這種 case 的話. 跟指標沒關. 你引數是左值就炸了 07/25 23:31
Feis: 我看了一下後我認同把 Args&& 改 Args 07/25 23:45
Feis: 確實是沒考慮到 overloading 的問題. 受教了. 07/25 23:46
dreamboat66: http://ideone.com/JSjgap 07/25 23:50
dreamboat66: 可是我還是不懂差別耶 可以解釋一下嗎 07/25 23:51
dreamboat66: 喔 我懂了@@也耍笨 thanks 07/25 23:53
LPH66: 啊, 我搞錯 perfect forwarding 的寫法了... 07/26 06:48
LPH66: perfect forwarding 需要函數參數的型別在函數自己的模版裡 07/26 06:49
LPH66: 這樣才能觸發 rvalue ref 的特殊模版推導規則 07/26 06:50
LPH66: 所以把 Proxy 的 operator() 加個模版就行了 07/26 06:51
LPH66: 變成像是這樣 http://ideone.com/ZBnLhn 07/26 06:51
LPH66: 呼叫方也改成有丟左值跟丟右值的狀況以資證明這是 OK 的 07/26 06:51
LPH66: 這個特殊推導規則是: 模版型別若在函式參數裡是 rvalue ref 07/26 06:53
LPH66: 的型式出現時, 推導結果視乎呼叫方該參數是左值還右值而定 07/26 06:54
LPH66: 左值則推導為 lvalue ref, 右值則推導為不帶 ref 的型態 07/26 06:54
LPH66: 這只在函式模版才有, class 模版不會也無法做這種推導 07/26 06:55
dreamboat66: 可是這樣改 導致外部想call by value莫名變成by ref 07/26 13:05
dreamboat66: 了 不是嗎?以l value 傳進去來講 07/26 13:05
Feis: 這裡的問題在於 function call 的參數型態已經由函式指標 07/26 14:14
Feis: 決定了. 07/26 14:14
Feis: 所以不管你傳甚麼他都會試著轉成可以函式指標參數的型態 07/26 14:15
Feis: 所以不管你要改成 Args 或加上 ActualArgs 都可以 07/26 14:15
Feis: 但是 forward 的存在是必要的 07/26 14:17
dreamboat66: 喔喔 傳lvalue看來他遲早會做一次copy 不管是args 07/26 15:43
dreamboat66: 先copy 還是actualarg 之後再copy 07/26 15:43
Feis: Args 跟 ActualArgs 的差別是推導的依據是函式指標的參數型 07/26 15:57
Feis: 態或者是呼叫的引數型態. copy 都是在同一個地方發生 07/26 15:58
Feis: (如果合法的話) 07/26 15:58
Feis: 阿. 我懂你意思. 是都在 operator() 但是時機不同. 我誤會了 07/26 16:08
Feis: 最近語言理解能力有點問題啊啊啊. 07/26 16:09
※ 編輯: dreamboat66 (180.218.186.119), 08/04/2015 22:53:38