[问题] 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