c++ 中 本身可以使用 & 来实现引用 ,那为什么还会出现ref 呢?
ref:
int f2(int &c){
c++;
cout<<"in function c = " << c<<endl;
}
int main(){
int c = 10;
f2(ref(c));
cout<<" out function c = " <<c <<endl;
}
&:
int f2(int &c){
c++;
cout<<"in function c = " << c<<endl;
}
int main(){
int c = 10;
f2(c);
cout<<" out function c = " <<c <<endl;
}
这两个得到的结果是一样的,那到底有什么区别呢?
当在使用std::bind时,是对参数直接拷贝,而不是引用。如下例子:
#include <iostream>
#include <functional>
using namespace std;
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;
}
int main(){
int n1 = 1 ,n2 = 10,n3 = 100;
function<void()> f1 = bind(f,n1,n2,ref(n3));
f1();
cout<<"out function a = "<<n1<<" b = "<<n2<<" c = "<<n3<<endl;
cout<<"out function a = "<<&n1<<" b = "<<&n2<<" c = "<<&n3<<endl;
f1();
cout<<"out function a = "<<n1<<" b = "<<n2<<" c = "<<n3<<endl;
cout<<"out function a = "<<&n1<<" b = "<<&n2<<" c = "<<&n3<<endl;
return 0;
}
输出:
in function a = 1 b = 10 c = 100
in function a = 0x56321f137c34 b = 0x56321f137c30 c = 0x7ffc5f2cbacc
out function a = 1 b = 10 c = 200
out function a = 0x7ffc5f2cbac4 b = 0x7ffc5f2cbac8 c = 0x7ffc5f2cbacc
in function a = 2 b = 20 c = 200
in function a = 0x56321f137c34 b = 0x56321f137c30 c = 0x7ffc5f2cbacc
out function a = 1 b = 10 c = 300
out function a = 0x7ffc5f2cbac4 b = 0x7ffc5f2cbac8 c = 0x7ffc5f2cbacc
在这里我们可以发现,在用bind的时候,如果不用ref,那么调用时函数里外就不是相同的地址,而使用ref的话,其地址在函数里外都是相同的。
ref能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。
不仅仅是在使用bind时,在使用thread进行编程时,也会发生这样的问题,thread的方法传递引用的时候,必须外层用ref来进行引用传递,否则会编译出错。
void method(int & a){ a += 5;}
using namespace std;
int main(){
int a = 0;
thread th(method,ref(a));
th.join();
cout << a <<endl;
//thread th2(method,a); //去掉注释会编译出错
//th2.join();
cout << a <<endl;
return 0;
}