编程学习
C++11 std::ref 的作用
00 分钟
2023-7-12
2023-11-23
type
status
date
slug
summary
tags
category
icon
password
Email

std::ref 功能

函数原型:
可以其返回一个 reference_wrapper
std::reference_wrapper 是包装引用于可复制、可赋值对象的类模板。它常用作将引用存储入无法正常保有引用的标准容器(类似 std::vector )的机制。
std::reference_wrapper 亦用于按引用传递对象给 std::bind 或 std::thread 的构造函数。

bind

这是一个简单的修改引用参数的值的函数。
如果我们想使用它,则直接调用 change(a,b) 即可,我们所传递的实参会自动到函数内转换为引用的形式。
但是如果我们想使用 std::bind ,我们可以写出这样的代码:
这是可以的,然后我们就可以像以前那样使用: f(a,b) 和上面的结果是一样的。
但是如果我们不使用 std::placeholders 占位符呢,我的两个参数就是 a和b,不会变了,因此我想要直接采用这样的形式:f()
我们会采用这样的方式:
bind直接指明 a和b 参数不就好了?
但是当我们执行 f() 后,却发现 a和b 的值没有发生变化!!!!!!!

因此推断出 bind函数的特性
  • std::bind 的参数被复制或移动,而且决不按引用传递,除非以 std::ref 或 std::cref 包装。
    • 换句话说就是:bind中参数的 & 符号是假的,虽然表面上是一个引用,但是执行的却是拷贝形式,除非你使用 std::ref 转换为真正的引用形式。
  • 如果 bind 存储的参数拥有类型 std::reference_wrapper<T>(例如,在起始的到 std::bind 调用中使用了 std::ref 或 std::cref),那么在bind函数操作的是 T&存储的参数按引用传递进入被调用的函数对象。
    • 换句话说:即只有使用 std::ref 转换后对于 bind 来说才是真正的引用类型。
  • 否则,普通的存储参数作为左值参数传递给:bind操作中的参数单纯地是T

因此想要实现 f() 的效果我们应该改成这样的形式:传递 std::ref 的形式

thread

对于传递给线程引用参数,我们也是同理:

总结:
  • std::ref 是一个 C++ 标准库函数模板,它将对象的引用转换为可复制的可调用对象。
  • 其使得在函数或线程等可调用对象中引用原始对象,而不是其副本。

评论
  • Twikoo
  • Valine