在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文为第七部分,目录请参阅概述部分: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语义永远不会发生即使没有外在的包装函数。 事实证明右值引用可以用来解决这类问题。它使得可以不用通过任何的重载就可以实现真正的完美转发。为了理解它是如果运作的,我们需要先看一下右值引用的两个规则。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论