关于std::ref函数

关于std::ref函数

概念

  • std::ref是C++11中引入的一个模板函数,用来产生std::reference_wrapper对象的函数,也就是我们常说的引用
  • std::ref会将传入参数转成引用返回
  • 相比较平常的&引用符号,我们可以使用std::ref来让泛型函数的参数类型推导推导成引用

函数原型

1
2
3
4
template<typename _Tp>
inline reference_wrapper<_Tp>
ref(_Tp& __t) noexcept
{ return reference_wrapper<_Tp>(__t); }

使用案例

  • 当我们希望在目标函数中对当前局部变量进行操作(也就是传入引用类型的变量),而函数模板作为一个中转站时,我们需要在当前调用函数时传入std::ref返回的对象作为参数
  • 在下面示例中,foo作为目标函数,我们可以看到传入的是int&类型的变量,用来对外面的局部变量操作,而在项目中有时候我们需要用到函数模板foo1这种泛型编程作为中转站,而我们如果直接将局部变量a传入而不进行std::ref操作,这样将会导致在函数模板foo1中的Args类型被推导成int而不是int&,这样我们在调用foo就无法对main函数中的局部变量a操作成功
  • 像这种情况的出现有很多,例如创建thread对象,传入线程函数和所需参数时,也是这种函数模板作为中转站的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>


void foo(int &x){
x+=1;
}

template <typename Fn,typename Args>
void foo1(Fn fn,Args args){
std::cout<<typeid(args).name()<<std::endl;
fn(args);
std::cout<<args<<std::endl;
}

int main (int argc, char *argv[]) {
int a=1;
//foo1(foo,a); //未使用std::ref
foo1(foo,std::ref(a)); //使用std::ref
std::cout<<a<<std::endl;

return 0;
}

//未使用std::ref运行结果
|| i //i就代表的int类型
|| 2
|| 1
|| Exited with code 0


//使用std::ref运行结果
|| St17reference_wrapperIiE
|| 2
|| 2
|| Exited with code 0

关于std::ref函数
https://moonfordream.github.io/posts/关于std-ref函数/
作者
Moon
发布于
2024年6月19日
许可协议