• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

翻译「C++RvalueReferencesExplained」C++右值引用详解Part7:PerfectForwarding(完 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文为第七部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.html

Move语义背后右值引用用来解决的另一个问题是完美转发问题。考虑下面这样简单的工厂函数:

template<typename T, typename Arg> 
shared_ptr<T> factory(Arg arg)
{ 
  return shared_ptr<T>(new T(arg));
}

显然,这里的目的是想要将arg参数通过工厂函数传递到T的构造函数中去。理想情况,就arg而言,一切应该表现得如同没有工厂函数一样,构造器直接被客户的代码调用:也就是完美转发。上面的代码很不幸在这种状况下失败了:它引入了一个额外的传值调用,当构造器使用引用类型作为参数时,那么这样就是很糟糕的了。

一个更为普遍的解决方案,例如被boost::bind所采用的,就是让外层的函数的参数使用引用类型:

template<typename T, typename Arg> 
shared_ptr<T> factory(Arg& arg)
{ 
  return shared_ptr<T>(new T(arg));
}

这样更好,但也并非完美。问题就是现在的工厂函数并不能被右值所调用:

factory<X>(hoo()); // error:如果hoo通过值返回
factory<X>(41); // error

这可以通过提供一个const reference的参数重载来解决:

template<typename T, typename Arg> 
shared_ptr<T> factory(Arg const & arg)
{ 
  return shared_ptr<T>(new T(arg));
}

这个方法有两个问题。首先,如果factor不仅仅只有一个,而是有很多个参数的话,你就需要提供所有对non-const和const reference参数的组合重载。因此,这种解决方案当面临到函数有很多参数的时候可伸缩性是很差的。

第二个,这种方法并不是完美的是因为它会阻挡move语义:在factory函数体中的T构造器重的参数是一个左值。因此,move语义永远不会发生即使没有外在的包装函数。

事实证明右值引用可以用来解决这类问题。它使得可以不用通过任何的重载就可以实现真正的完美转发。为了理解它是如果运作的,我们需要先看一下右值引用的两个规则。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#钩子类几乎捕获键盘鼠标所有事件发布时间:2022-07-13
下一篇:
C#XMLOperate发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap