Reputation: 541
I am learning C++11 thread and tried to write a thread changing the shared memory. I used std::ref
and std::move
respectively. I ran the code using: g++ eg3.cpp -std=c++11 -pthread
. However I found std::move
does not work on my mac. I got error like this:
In file included from eg3.cpp:1: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:337:5: error:
attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
...
My code is as follows:
#include<thread>
#include<iostream>
#include<mutex>
#include<condition_variable>
#include<string>
#include<functional>
#include<utility>
using namespace std;
int main(){
string s = "Hello!";
cout << "Main before: " << s << endl;
// thread t([](string& s){cout << s << endl; s = "Ni hao!";}, ref(s)); //// This works!
// thread t([](string& s){cout << s << endl; s = "Ni hao!";}, move(s)); //// This does not work
t.join();
cout << "Main after: " << s << endl;
return 0;
}
Upvotes: 5
Views: 3777
Reputation: 46598
You just need to make the lambda takes string
(by value) or string const &
(by constant reference) or string &&
(rvalue reference) to support move. In this case, because you are modifying s
, and you can't use string const &
.
thread t([](string && s){cout << s << endl; s = "Ni hao!";}, move(s));
It failed because you can't pass rvalue reference (string &&
) to a function/lambda that takes lvalue reference (string &
).
A simplified example is
void test(std::string &) {}
void test2(std::string &&) {}
void test3(std::string const&) {}
void test4(std::string) {}
int main(){
std::string s;
test(std::move(s)); // fail
test2(std::move(s)); // ok
test3(std::move(s)); // ok
test4(std::move(s)); // ok
}
Upvotes: 2