std :: reference_wrapper和简单指针之间的区别? [英] Difference between std::reference_wrapper and simple pointer?

查看:1561
本文介绍了std :: reference_wrapper和简单指针之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么需要 std :: reference_wrapper ?应该在哪里使用?它和一个简单的指针有什么不同?它的性能如何与简单的指针相比?

Why is there a need to have std::reference_wrapper? Where should it be used? How is it different from a simple pointer? How its performance compares to a simple pointer?

推荐答案

std :: reference_wrapper 与模板组合使用。它通过存储一个指针来包装一个对象,允许重新分配和复制,同时模仿它的通常的语义。它还指示某些库模板存储引用而不是对象。

std::reference_wrapper is useful in combination with templates. It wraps an object by storing a pointer to it, allowing for reassignment and copy while mimicking its usual semantics. It also instructs certain library templates to store references instead of objects.

考虑STL中的复制函子的算法:你可以通过简单地传递引用包装器到函子而不是函子本身:

Consider the algorithms in the STL which copy functors: You can avoid that copy by simply passing a reference wrapper referring to the functor instead of the functor itself:

unsigned arr[10];
std::mt19937 myEngine;
std::generate_n( arr, 10, std::ref(myEngine) ); // Modifies myEngine's state

这是因为...

  • reference_wrappers overload operator() so they can be called just like the function objects they refer to:

std::ref(myEngine)() // Valid expression, modifies myEngines state


  • ...(un)像普通引用一样,复制(和赋值) reference_wrappers

    int i, j;
    auto r = std::ref(i); // r refers to i
    r = std::ref(j); // Okay; r refers to j
    r = std::cref(j); // Error: Cannot bind reference_wrapper<int> to <const int>
    


  • 复制引用封装实际上等同于复制一个指针,它是一样便宜,它得到。所有使用它的函数调用(例如 operator())应该只是内联,因为它们是一行。

    Copying a reference wrapper is practically equivalent to copying a pointer, which is as cheap as it gets. All the function calls inherent in using it (e.g. the ones to operator()) should be just inlined as they are one-liners.

    reference_wrapper 是通过创建的 std :: ref std :: cref

    reference_wrappers are created via std::ref and std::cref:

    int i;
    auto r = std::ref(i); // r is of type std::reference_wrapper<int>
    auto r2 = std::cref(i); // r is of type std::reference_wrapper<const int>
    

    模板参数指定所引用对象的类型和cv-qualification; r2 指的是一个 const int ,并且只会引用 const int 。使用 const 函数引用包装器的调用只会调用 const 成员函数 operator s。

    The template argument specifies the type and cv-qualification of the object referred to; r2 refers to a const int and will only yield a reference to const int. Calls to reference wrappers with const functors in them will only call const member function operator()s.

    不允许使用Rvalue初始值设定项,因为允许它们会比正常做更多的伤害。由于无论如何都会移动右值(以及有保证的副本删除)即使这是部分避免的),我们不改进语义;我们可以引入悬挂指针,因为参考包装不会延长指针的生命周期。

    Rvalue initializers are disallowed, as permitting them would do more harm than good. Since rvalues would be moved anyway (and with guaranteed copy elision even that's avoided partly), we don't improve the semantics; we can introduce dangling pointers though, as a reference wrapper does not extend the pointee's lifetime.

    如前所述,通过传递相应的参数到 tuple ,可以指示 make_tuple code> reference_wrapper :

    As mentioned before, one can instruct make_tuple to store a reference in the resulting tuple by passing the corresponding argument through a reference_wrapper:

    int i;
    auto t1 = std::make_tuple(i); // Copies i. Type of t1 is tuple<int>
    auto t2 = std::make_tuple(std::ref(i)); // Saves a reference to i.
                                            // Type of t2 is tuple<int&>
    


    $ b <这里,不允许使用rvalues作为参数。

    Note that this slightly differs from forward_as_tuple: Here, rvalues as arguments are not allowed.

    std :: bind 显示相同的行为:它不会复制参数,但如果它是 reference_wrapper ,则存储引用。如果使用 bind -functor时,不需要复制参数(或函数!),而是保持在作用域中,这将非常有用。

    std::bind shows the same behavior: It won't copy the argument but store a reference if it is a reference_wrapper. Useful if that argument (or the functor!) need not be copied but stays in scope while the bind-functor is used.

    • There is no additional level of syntactical indirection. Pointers have to be dereferenced to obtain an lvalue to the object they refer to; reference_wrappers have an implicit conversion operator and can be called like the object they wrap.

    int i;
    int& ref = std::ref(i); // Okay
    


  • reference_wrapper s ,与指针不同,不具有空状态。必须使用初始化参考或其他 reference_wrapper

  • reference_wrappers, unlike pointers, don't have a null state. They have to be initialized with either a reference or another reference_wrapper.

    std::reference_wrapper<int> r; // Invalid
    


  • 相似性是浅拷贝语义:指针和 reference_wrapper 可以重新分配。

    这篇关于std :: reference_wrapper和简单指针之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆