std::ref()构建一个reference_wrapper对象并返回,该对象拥有传入的变量的引用。如果该对象本身就是reference_wrapper类型,则创建该对象的一个副本并返回。
在非模版的情况下,ref不能实现引用传递,只有模版自动推导类型或类型隐式转换时才行。ref能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型
#include <iostream>
#include <functional>
#include <vector>
#include <thread>
using namespace std;
// 使用场景
// 1、std::ref在函数式编程(如std::bind)的使用时,是对参数直接拷贝,而不是引用
// 2、在多线程时传递参数使用
void f(int& a, int& b, int& c)
{
cout << "in function a = " << a << " b = " << b << " c = " << c << endl;
cout << "in function a = " << &a << " b = " << &b << " c = " << &c << endl;
a += 1;
b += 10;
c += 100;
}
void f(int &a) { a += 5;}
int main() {
int a = 5;
thread th(f, std::ref(a));
th.join();
cout << a << endl; // a = 10;
int n1 = 1, n2 = 10, n3 = 100;
int r1 = n1;
int& r2 = n2;
function<void()> f1 = bind(f, r1, r2, ref(n3));
// 即便是引用类型,bind 传入的还是其值的拷贝,第三个参数传入 reference_wrapper 对象,该对象可隐式的转换为值的引用
f1();
cout << "out function a = " << n1 << " b = " << n2 << " c = " << n3 << endl;
cout << "out function a = " << &n1 << " b = " << &n2 << " c = " << &n3 << endl;
r1 = 100;
r2 = 100;
f1();
cout << "out function a = " << n1 << " b = " << n2 << " c = " << n3 << endl;
cout << "out function a = " << &n1 << " b = " << &n2 << " c = " << &n3 << endl;
/*
in function a = 1 b = 10 c = 100
in function a = 0x55763d32be84 b = 0x55763d32be80 c = 0x7fff1ba6fa18
out function a = 1 b = 10 c = 200
out function a = 0x7fff1ba6fa10 b = 0x7fff1ba6fa14 c = 0x7fff1ba6fa18
in function a = 2 b = 20 c = 200
in function a = 0x55763d32be84 b = 0x55763d32be80 c = 0x7fff1ba6fa18
out function a = 1 b = 100 c = 300
out function a = 0x7fff1ba6fa10 b = 0x7fff1ba6fa14 c = 0x7fff1ba6fa18
*/
return 0;
}