C ++ 11 functor in a thread puzzle

Please consider the following code snippet. Using GCC 4.6.1, x becomes 0 , and y becomes 1 .

Why do I get different results with and without using a separate thread? How can I change the code so that both versions give the same result (i.e., the Integer value increases by 1?)

Thanks.

 struct functor{ void operator()(int & x){ ++x; } }; void tfunc(functor & f, int & x){ f(x); } int main(){ functor f; int x = 0, y = 0; std::thread t = std::thread(tfunc, f, x); t.join(); std::cout << "with thread " << x << std::endl; f(y); std::cout << "without thread " << y << std::endl; } 
+4
source share
2 answers

It’s easy to understand what is going on. Just replace int with an uncopyable type (one with a private copy constructor), and the compiler will tell you exactly where libstdc++ trying to copy the argument instead of using the link. In my case, this is line 138 in the standard <tuple> header.

Whether this is the correct implementation of the standard, I can’t say at the moment.

UPDATE . The standard states that each argument to std::thread::thread must satisfy the MoveConstructible requirement and that the actual arguments passed to the thread function are constructed from a string of std::thread::thread arguments. It means that

  • the stream function receives copies of the arguments, and
  • Originals can be destroyed in the process.

Thus, the transfer of material by reference will not work.

+2
source

It looks like when std::thread(tfunc, f, x) is called, x is copied and the reference to the temporary value is passed to the functor, so calling the functor will not change the value of x. I think that in general, STL algorithms / functions always copy arguments. If you want your funter call to change x, you can use a pointer, since even the pointer is copied, the copy still points to the same address.

0
source

Source: https://habr.com/ru/post/1392896/


All Articles