Search code examples
c++multithreadingreference-wrapper

C++ reference wrapper as function argument


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()?


Solution

  • 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.

    LIVE