std :: reference_wrapper和简单指针之间的区别? [英] Difference between std::reference_wrapper and simple pointer?
问题描述
为什么需要 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_wrapper
s overloadoperator()
,因此它们可以像它们引用的函数对象一样被调用:
…
reference_wrapper
s overloadoperator()
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_wrapper
s 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.
-
没有额外的语法间接。指针必须被取消引用以获得它们引用的对象的左值;
reference_wrapper
有一个隐式的转换运算符< a>并且可以像它们包装的对象一样被调用。
There is no additional level of syntactical indirection. Pointers have to be dereferenced to obtain an lvalue to the object they refer to;
reference_wrapper
s 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_wrapper
s, 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屋!