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

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

Links booklink

Contact Us: admin [ a t ] ucptt.com