为什么需要 std::reference_wrapper
?应该在哪里使用?它与简单的指针有何不同?它的性能与简单指针相比如何?
原文由 Laurynas Lazauskas 发布,翻译遵循 CC BY-SA 4.0 许可协议
为什么需要 std::reference_wrapper
?应该在哪里使用?它与简单的指针有何不同?它的性能与简单指针相比如何?
原文由 Laurynas Lazauskas 发布,翻译遵循 CC BY-SA 4.0 许可协议
std::reference_wrapper<T>
至少有两个激励目的:
std::for_each()
,它按值获取其函数对象参数。为避免复制对象,您可以使用 std::for_each(begin, end, std::ref(fun));
将参数作为 std::reference_wrapper<T>
传递给 std::bind()
表达式通过引用而不是值绑定参数是很常见的。
std::reference_wrapper<T>
和 std::make_tuple()
时,对应的元组元素变成 T&
而不是 T
: T object;
f(std::make_tuple(1, std::ref(object)));
原文由 Dietmar Kühl 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
std::reference_wrapper
与模板结合使用很有用。它通过存储指向对象的指针来包装对象,允许在模仿其通常语义的同时重新分配和复制。它还指示某些库模板存储引用而不是对象。考虑 STL 中复制函子的算法:您可以通过简单地传递引用函子而不是函子本身的引用包装器来避免该复制:
这有效,因为……
reference_wrapper
s 重载operator()
所以它们可以像它们引用的函数对象一样被调用:reference_wrappers
只是分配指针。复制引用包装器实际上等同于复制指针,这很便宜。使用它时固有的所有函数调用(例如
operator()
的函数调用)都应该被内联,因为它们是单行的。reference_wrapper
通过std::ref
和std::cref
创建:模板参数指定所引用对象的类型和 cv 限定;
r2
指的是const int
并且只会产生对const int
的引用。使用const
函数调用引用包装器将仅调用const
成员函数operator()
s。不允许使用右值初始化器,因为允许它们弊大于利。由于无论如何都会移动右值(并且 保证复制省略,即使部分避免),我们不改进语义;我们可以引入悬空指针,因为引用包装器不会延长指针的生命周期。
图书馆互动
如前所述,可以指示
make_tuple
将引用存储在生成的tuple
中,方法是将相应的参数传递给reference_wrapper
:请注意,这与
forward_as_tuple
略有不同:此处,不允许将右值作为参数。std::bind
显示相同的行为:如果它是reference_wrapper
,它不会复制参数但存储引用。如果该参数(或函子!)不需要复制但在使用bind
函子时保持在范围内,则很有用。与普通指针的区别
reference_wrapper
s 有一个隐式 转换运算符,可以像它们包装的对象一样调用。reference_wrapper
s,不像指针,没有空状态。它们必须 使用引用或另一个reference_wrapper
进行初始化。reference_wrapper
可以重新分配。