From my understanding, reference wrapper is just a wrapper on reference, nothing too special about it. But why it is treated as the reference itself (rather than the wrapper) inside the function when passed as a function argument?
#include <iostream>
#include <functional>
using namespace std;
void f(int& x){
cout<<"f on int called"<<endl;
}
void f(reference_wrapper<int>& x){
cout<<"f on wrapper called"<<endl;
}
int main(){
int x = 10;
f(ref(x)); // f on int called, why?
reference_wrapper<int> z = ref(x);
f(z); // f on wrapper called, this makes sense though
}
why does ref(x) treated as x itself inside function call? I come to this problem because I was trying to understand the use of ref() when passing data among different threads. I think the ref() is necessary so any function argument with '&' need not be rewritten to avoid threads interfere with each other. But why the threads can treat ref(x) as x without using x.get()?
CodePudding user response:
f(ref(x)); // f on int called, why?
Because std::reference_wrapper
has a conversion operator to the stored reference; ref(x)
returns an std::reference_wrapper
, which could be converted to int&
implicitly.
void f(reference_wrapper<int>& x)
takes lvalue-reference to non-const, std::ref
returns by-value, i.e. what it returns is an rvalue which can't be bound to lvalue-reference to non-const. Then f(ref(x));
calls the 1st overloaded f
instead of the 2nd one. If you change it to void f(reference_wrapper<int> x)
or void f(const reference_wrapper<int>& x)
then it'll be called.