Reputation: 2491
I am learning C++11 threads and facing problems in compiling the below program.
I am unable to figure out the problem as everything seems correct.
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
void hello(string& s)
{
s = "HELLO";
cout << "Hello thread created" << endl;
}
int main()
{
cout << "main thread created" << endl;
string s = "HEY";
thread t(hello, s);
t.join();
cout << s << endl;
return 0;
}
My g++ version is 4.8.5 and I am compiling it on CentOS-7.2 using command :
g++ thread.cpp -std=c++11 -pthread
The error I am getting is:
In file included from /usr/local/include/c++/4.8.5/thread:39:0, from thread.cpp:2: /usr/local/include/c++/4.8.5/functional: In instantiation of ‘struct std::_Bind_simple))(std::basic_string&)>’: /usr/local/include/c++/4.8.5/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::basic_string&); _Args = {std::basic_string, std::allocator >&}]’ thread.cpp:17:20:
required from here /usr/local/include/c++/4.8.5/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of))(std::basic_string&)>’ typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/local/include/c++/4.8.5/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of))(std::basic_string&)>’ _M_invoke(_Index_tuple<_Indices...>)
Any help would be highly appreciated.
Upvotes: 1
Views: 835
Reputation: 30569
std::thread
keeps a copy of the objects that it will pass to the thread function, and when it starts the new thread it passes those arguments to the thread as rvalues. Non-const lvalue-references references cannot bind to rvalues, so the parameter for your hello
function cannot be bound to the object std::thread
tries to pass to it.
If you want to avoid this copying behavior, use std::reference_wrapper
:
int main()
{
cout << "main thread created" << endl;
string s = "HEY";
thread t(hello, std::ref(s));
t.join();
cout << s << endl;
return 0;
}
std::reference_wrapper<T>
is an object that holds a reference to an object, and, when copied, copies only the reference. It also has an implicit conversion to T&
, so when std::thread
passes the std::reference_wrapper<std::string>
object to your hello
function, it will be implicitly converted to a reference to the original object used to construct it in your main thread.
Upvotes: 4