Error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function
Objects of type std::thread
can't be copied. You are best off to just initialize the objects in the member initializer list:
class StreamServerClient{public: bool* terminate; std::thread client; void DoNothing(); StreamServerClient(SOCKET clientSock, bool* ptTerm); StreamServerClient(StreamServerClient&& other); ~StreamServerClient();};StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm) : terminate(ptTerm) , client(std::thread(&StreamServerClient::DoNothing, this)) {}StreamServerClient::StreamServerClient(StreamServerClient&& other) : terminate(other.terminate) , client(std::move(other.client)) {}
I ommitted the default constructor (note that your version doesn't work because it tries to assign a value to the result of dereferencing an uninitialized pointer) and instead added a move constructor: when pushing back to the std::vector<...>
this constructor will be called when providing something which looks like a temporary (i.e., something which either is a temporary or is made to look like one, e.g., using std::move()
).
An std::thread
object is not copyable. When this line is called:
clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate));
The StreamServerClient
object you create needs to be added to the clients
vector, but the only way to do that is by copying it because your StreamServer
object does not have a move constructor defined. The default copy constructor for StreamServerClient
is generated, and what the default copy constructor in C++11 does is, it calls the copy constructors of all of the data members.
In this case it is calling the copy constructor of the std::thread
data member, which is deleted.
The reason std::thread
s can't be copied is that a std::thread
object corresponds to a thread of execution. You should refactor your code, IMO. You could hack together a move constructor for StreamServerClient
, but I think there are cleaner solutions, for example, replacing the std::thread
with a pointer to std::thread
and initializing the thread with a completely separate call.
Edit: In general I would say it is unwise to branch a new thread in an object's contructor, because it is too delicate an operation. (It can fail, then you have to deal with exceptions, etc.) Although probably C++ purists will disagree with me.
Edit: Had stupid terminology.