免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: lost_templar
打印 上一主题 下一主题

[C++] 一段自动求导的代码,C++er 来看下 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
11 [报告]
发表于 2013-04-13 20:59 |只看该作者
本帖最后由 lost_templar 于 2013-04-13 21:04 编辑

回复 8# 幻の上帝


    确实是 copy constructor 被触发了的原因,我加入这段代码:
  1.         derivative& operator = ( const derivative& other )
  2.         {
  3.             ff = [&](Types... vts) -> return_type { return other( vts... ); };
  4.         }

  5.         derivative( const derivative& other )
  6.         {
  7.             ff = [&](Types... vts) -> return_type { return other( vts... ); };
  8.         }
复制代码
到类中之后,
  1.     auto const& dds = derivative<0, double(double)>(ds);
  2.     std::cout << "d( d sin(x) / dx) / dx at (0.0) is " << derivative<0, double(double)>(dds)( 0.0 ) << "\n";
复制代码
输出正确的结果 0, 但是触发了 move constructor 的这段代码依旧输出 1:

  1. std::cout << "d( d sin(x) / dx) / dx at (0.0) is " << derivative<0, double(double)>(derivative<0, double(double)>(ds) )( 0.0 ) << "\n";
复制代码
尽管我已经把 move constructor 和 move assignment operator 写为:

  1.         derivative( derivative&& other )
  2.         {
  3.             ff = [&](Types... vts) -> return_type { return other( vts... ); };
  4.         }
  5.         derivative& operator = ( derivative&& other )
  6.         {
  7.             ff = [&](Types... vts) -> return_type { return other( vts... ); };
  8.         }
复制代码
而如果将 move constructor 和 move assignment operator 定义为 delete,则上边的代码不能通过编译 {:3_193:}

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2013-04-13 21:32 |只看该作者
回复 5# 幻の上帝


    我已经在 http://134.60.10.69/gitweb/ 更新了代码,现在只有
  1. derivative<0, double(double)>(derivative<0, double(double)>(ds) )( 0.0 )
复制代码
这个搞不定了,它非要去调用 move constructor

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2013-04-13 23:42 |只看该作者
回复 12# lost_templar

觉得自己进入误区了,对于这样的代码
  1. derivative a(something);
  2. A b = a;
复制代码
让 a 和 b 具有不同的行为,本身就是很邪恶的{:3_182:}

   

论坛徽章:
0
14 [报告]
发表于 2013-04-14 08:54 |只看该作者
回复 13# lost_templar

……我也试出来了,是copy ctor的问题。再包装一层std::function或lambda传进去就正常了。
确实,如果自己重写copy ctor,可以解决一部分问题,不过会让代码的意义不太明确。
可以学标准库的做法,考虑写一个模版(比如叫make_derivative)转发参数,并对derivative提供重载,这样就区分开来了。而且可以让用户不用照抄模版实参。
或者提供显式的tag放在构造函数里,然后提供tag的重载,不过可能写起来比较麻烦一点。
另外建议考虑一下使用std::result_of或decltype推导返回类型。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
15 [报告]
发表于 2013-04-14 16:35 |只看该作者
回复 14# 幻の上帝

非常感谢!
非常有用的建议,我会仔细地研究一下标准库,再看下怎么设计这里的接口。


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP