0

So according to https://en.cppreference.com/w/cpp/thread/thread/thread: the copy constructor for std::thread is deleted and is the reason I cannot do (results in a compilation error):

std::thread t1;
std::thread t2 = t1;

However I am somehow able to do:

std::thread t1;
t1 = std::thread();

I was under the impression that the above code creates a temporary std::thread object and copies it into t1 but the copy constructor doesn't exist (as is shown in the top snippet which doesn't compile).

So what exactly is going on in the second snippet?

user3690467
  • 3,049
  • 6
  • 27
  • 54
  • Are you familiar with move semantics? If not, see [What is move semantics?](https://stackoverflow.com/questions/3106110/what-is-move-semantics) – François Andrieux Jan 07 '21 at 21:07
  • Since the left side of the equal sign in `t1 = std::thread();` is an existing variable, not a declaration, you should be thinking [assignment](https://en.cppreference.com/w/cpp/thread/thread/operator%3D) rather than [construction](https://en.cppreference.com/w/cpp/thread/thread/thread). *(In one sense it does not matter since copy-assignment is also deleted. Hence this is a comment, not an answer.)* – JaMiT Jan 07 '21 at 21:15

1 Answers1

6

The second one uses move assignment. std::thread can be moved, but not copied.

This should also work: std::thread t2 = std::move(t1); , which will leave t2 managing whatever thread t1 was managing , and t1 will be empty.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • If std::thread *did* have a copy constructor would it then be copied instead? I.e is the behavior to try and copy and use move instead if there is no copy constructor? or does doing this always call move? – user3690467 Jan 07 '21 at 21:14
  • 1
    @user3690467: No; move is an optimized copy. Move is used if it wouldn't cause a problem, such as in the cases of prvalues or direct request (ie: `std::move`). – Nicol Bolas Jan 07 '21 at 21:17
  • 1
    In case it's needed, here's some reading to understand some of the above terminology: [What are rvalues, lvalues, xvalues, glvalues, and prvalues?](https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues) – user4581301 Jan 07 '21 at 21:19
  • 1
    Assignment or construction from rvalues tries the move first, only falling back to copy if the move constructor/assignment-op didn't exist. (note that "normal" classes default to having compiler-generated move operations, so there would be no fallback in those cases -- full discussion of this is beyond scope of comments :) – M.M Jan 07 '21 at 21:21