美文网首页
转载--std::ref应用

转载--std::ref应用

作者: hijiang | 来源:发表于2019-04-24 23:49 被阅读0次

    在std::promise范例中,使用了std::ref将future对象传递给引用参数类型的任务函数。

    std::promise示例

    如果直接传入pr,将会出现编译错误:

    error C2661: “std::tuple,std::promise>::tuple”: 没有重载函数接受 2 个参数

    说明函数调用的参数类型不匹配。

    查看thread的源代码,其构造函数依赖于一个rvalue-reference类型的variaic templates参数列表:

    template::type, thread>::value>::type>explicit

    thread(_Fn&& _Fx, _Args&&... _Ax){

    // construct with _Fx(_Ax...)

    _Launch(&_Thr,

    _STD make_unique, decay_t<_Args>...> >(

    _STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));

    }

    其中的“_Args&&... _Ax”也是C++11引入的新特性:Variadic templates,它允许函数可以接受任意个不同类型的参数,类似于C语言中的可变参数。在参考文档[4]中说,”However, thanks tovariadic templates, programming new features usingtemplates has becomeeasier,clearer & morememory-efficient.“,为什么内存效率更高呢?参考[6]中解释说:参数列表所形成的一个parameter pack在编译期间被解包,C++利用编译期的处理实现了运行时效率优化。参考[5]中说:”Variadic templates are a trustworthy solution to implement delegates and tuples. And, instead of C-style ellipsis mechanism, variadic templates can offer a typesafer solution to replace them.“具体如何实现delegates和tuples,另行描述。

    除了可变模板,另外两个相关的新技术是rvalue-reference和reference_wrapper,这两者和move语义是紧密相连的,如此节省了很多右值对象的复制构造开销。

    std::ref(pr)返回的对象类型是一个reference_wrapper,而不是对pr的直接引用(T&,即std::promise&)。

    换一个参考[7]中的例子:

    bind与reference_wrapper的示例第一部分

    上述代码的结果是0!为什么?因为bind方法通过传值方式传入参数,在被传递给绑定目标add方法之前,变量”result“已经被重新拷贝了。因为bind必须确保传入的参数是持续可用的。

    解决方法很简单,使用reference_wrapper:

    bind与reference_wrapper的示例第二部分

    使用如下代码定义reference_wrapper对象:

     reference_wrapper r=x;// or auto r = ref(x); 

    通过r对象的get函数(r.get()),r的作用与直接引用完全一样。

    还可以用来创建引用数组,例如:

    引用数组的创建

    std::reference_wrapper在泛型代码中用处广泛,它存储的是对象的指针,有引用的全部功能,还实现了引用的拷贝(包括拷贝构造和拷贝赋值),可以在程序中存储引用而不是整个对象。

    reference_wrapper和shared_ptr如何选择?两者都可以实现指针层面的复制和操作,但是前者不允许默认构造函数,在容器中也不能使用resize等方法。另外可能还有一些不同之处,但是基本上没有太大区别了。

    参考资料:

    [1] http://stackoverflow.com/questions/33240993/c-difference-between-stdreft-and-t

    [2] http://stackoverflow.com/questions/26766939/difference-between-stdreference-wrapper-and-simple-pointer

    [3] http://stackoverflow.com/questions/31013689/why-does-stdthread-take-function-to-run-by-rvalue

    [4] http://softwareengineering.stackexchange.com/questions/273448/polymorphic-template-container-shared-ptr-vs-reference-wrapper

    [5] http://www.cplusplus.com/articles/EhvU7k9E/

    [6]Real-Time C++: Efficient Object-Oriented and Template Microcontroller Programming,2015-12,Christopher Kormanyos

    [7] https://oopscenities.net/2012/08/09/reference_wrapper/

    作者:Brent姜

    链接:https://www.jianshu.com/p/5b91c51bd856

    来源:简书

    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    相关文章

      网友评论

          本文标题:转载--std::ref应用

          本文链接:https://www.haomeiwen.com/subject/efsogqtx.html