What would be a "Hello, World!" example for "std::ref"?
Can somebody give a simple example which demonstrates the functionality of std::ref
? I mean an example in which some other constructs (like tuples, or data type templates) are used only if it is impossible to explain std::ref
without them.
I found two questions about std::ref
here and here. But in the first one it goes about a bug in a compiler and in the second one, examples of use of std::ref
do not contain std::ref
and they involve tuples and data type templates which make understanding of these examples complex.
You should think of using std::ref
when a function:
- takes a template parameter by value
- copies/moves a template parameter, such as
std::bind
or the constructor forstd::thread
.
std::ref
creates a copyable value type that behaves like a reference.
This example makes demonstrable use of std::ref
.
#include <iostream>
#include <functional>
#include <thread>
void increment( int &x )
{
++x;
}
int main()
{
int i = 0;
// Here, we bind increment to a COPY of i...
std::bind( increment, i ) ();
// ^^ (...and invoke the resulting function object)
// i is still 0, because the copy was incremented.
std::cout << i << std::endl;
// Now, we bind increment to std::ref(i)
std::bind( increment, std::ref(i) ) ();
// i has now been incremented.
std::cout << i << std::endl;
// The same applies for std::thread
std::thread( increment, std::ref(i) ).join();
std::cout << i << std::endl;
}
Output:
0
1
2
void PrintNumber(int i) {...}
int n = 4;
std::function<void()> print1 = std::bind(&PrintNumber, n);
std::function<void()> print2 = std::bind(&PrintNumber, std::ref(n));
n = 5;
print1(); //prints 4
print2(); //prints 5
std::ref
is mainly used to encapsulate references when using std::bind
(but other uses are possible of course).
Another place where you may need std::ref is when passing objects to threads where you want each thread to operate on the single object and not a copy of the object.
int main(){
BoundedBuffer buffer(200);
std::thread c1(consumer, 0, std::ref(buffer));
std::thread c2(consumer, 1, std::ref(buffer));
std::thread c3(consumer, 2, std::ref(buffer));
std::thread p1(producer, 0, std::ref(buffer));
std::thread p2(producer, 1, std::ref(buffer));
c1.join();
c2.join();
c3.join();
p1.join();
p2.join();
return 0; }
where you wish various functions running in various threads to share a single buffer object. This example was stolen from this excellent tutorial ( C++11 Concurrency Tutorial - Part 3: Advanced locking and condition variables (Baptiste Wicht) ) (hope I did the attribution correctly)