What's the difference between passing an argument by reference and using std::ref?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void increment(int& i)
{
	i++;
}

int main()
{
	int i = 0;

	increment(std::ref(i));
	std::cout << i << std::endl;

	increment(i);
	std::cout << i << std::endl;

	system("pause");
	return 0;
}

Program would output:
1
2


What I fail to understand is how std::ref differs from passing an argument by reference. As I've explained in the example above, whether I used std::ref or not, the value of i in main was incremented.
As far as I've read, std::ref "is a value type that emulates the functionality of a reference." (http://stackoverflow.com/questions/15530460/what-would-be-a-hello-world-example-for-stdref)
So what is the core purpose of using std::ref, and why/when would I want to use it instead of just plain passing arguments by reference?
Last edited on
So what is the core purpose of using std::ref, and why/when would I want to use it instead of just plain passing arguments by reference?
Maybe this will illustrate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <functional>

void inc(int& x)
{
    ++x;
}

template <typename T, typename U>
void frwd(T func, U arg)
{
    func(arg);
}

int main()
{
    int x = 0;

    frwd(inc, x);
    std::cout << x << '\n';

    frwd(inc, std::ref(x));
    std::cout << x << '\n';
}
0
1
Another way was to write frwd<void(int&), int&>(inc, x); which is not pretty. And imagine if template had 5 arguments? Of called another template inside?
With wide use of value semantic in standard library, sometimes it is really useful.
So it's helpful when the reference is forwarded towards other functions/methods? Seems pretty cool.
> it's helpful when the reference is forwarded towards other functions/methods?

Only if the function template accepts a parameter by value, but it needs to be forwarded as a reference. This is a situation that does occur, but in practice it is quite rare.

The usual mechanism is for the function template to accept the parameter as a universal reference, and then use perfect forwarding.
See: http://en.cppreference.com/w/cpp/utility/forward


std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is
frequently used as a mechanism to store references inside standard containers
(like std::vector) which cannot normally hold references.
...
std::reference_wrapper is also used to pass objects to std::bind or to the constructor of std::thread by reference.
- http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

See the example at the bottom of the page.
Last edited on
Topic archived. No new replies allowed.