I'm having a hard time with the following std::thread's note (from cppref):
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g., with std::ref or std::cref).
Okay - since there's no guarantee that the argument will remain alive up until the end of the thread's execution, it makes sense that the thread itself should own it. Now, consider the following code snippet:
#include <iostream>
#include <thread>
void
tellValue(int& value)
{
std::cout << "The value is: " << value << std::endl;
}
int
main()
{
int mainThreadVariable{0};
std::thread thr0{tellValue, mainThreadVariable};
thr0.join();
return 0;
}
Clang does not accept this, neither should it - the thread doesn't own mainThreadVariable. Why, however, does it accept this:
#include <iostream>
#include <thread>
int
main()
{
int mainThreadVariable{0};
std::thread thr0{[&]()
{
std::cout << "The value is: " << mainThreadVariable
<< std::endl;
++mainThreadVariable;
}};
thr0.join();
std::cout << "The value is: " << mainThreadVariable << std::endl;
return 0;
}
The latter outputs the following:
./PassingArgumentsToAThread
The value is: 0
The value is: 1
The thread neither copied mainThreadVariable nor moved it, because it is safe and sound at the end of the main thread. The callable object captured it by reference, so why was this allowed?
must be invocable after conversion to rvalues- this means lvalue referenceint&can't bind rvalue. Once you declare the valueconst int&, it can.