c++ - Why is it impossible to move a variable to another thread -
what reason can't move object thread? there situations useful. example:
you create loop accepts incoming socket connections. nice move incoming connections thread handle connection. don't need connection anymore in accept loop. why should create pointer?
a small test case:
#include <iostream> #include <thread> using namespace std; class pointertest { public: pointertest() {cout << "constructor";} pointertest(pointertest &pointertest) {cout << "copy";} pointertest(pointertest &&pointertest) {cout << "move";} ~pointertest() {cout << "destruct";} }; void foo(pointertest &&pointertest) { } int main() { pointertest pointertest; foo(std::move(pointertest)); //works thread test(foo,std::move(pointertest)); //**cannot convert parameter 1 'pointertest' 'pointertest &&'** }
the std::thread
constructor has treat arguments give differently forwarding functions.
the reason due questions of when thread gets started. if part of function invocation created function argument gets run long after thread
object created (which entirely legal behavior), object needs moved may have long since been destroyed.
just consider altered version of code:
std::thread some_func() { pointertest pointertest; thread test(foo,std::move(pointertest)); return test; }
this valid (the thread moved out of function). however, there's big problem. foo
may not have been called yet. , since foo
takes parameter reference, has reference stack variable has been destroyed.
that's bad. if foo
took parameter value, change nothing. because actual movement parameter doesn't happen until indeterminate time after thread has been started. attempt move parameter still use rvalue reference stack variable has been destroyed. again bad.
therefore, std::thread
constructor different. copy/moves arguments give internal storage (this done on current thread). uses values arguments actual function call (this done on new thread).
according standard, thread constructor should treat pass these internal variables functions temporaries. standard states invoke (decay_copy ( std::forward<f>(f)), decay_copy (std::forward<args>(args))...)
, decay_copy
stuff happens on original thread, while invoke
part happens on new thread.
so seems thread
implementation isn't able forward non-copyable parameters through correctly. should able pass non-copyable type; arguments required moveconstructible
.
so appear bug in implementation.
Comments
Post a Comment