Error C2280: 'std :: thread :: thread (const std :: thread &)': attempt to reference a remote function

I had a problem creating a static VC ++ library that uses standard C ++ 11 streams.

I currently have two classes, and I can declare, and then define a thread that just works fine for my start class (which is declared last). At this point, the code is only a socket listener, which then creates an object of another class to process each received client. These children must create the streams necessary for parallel data collection, coding, and transmission.

The problem is this: if I declare std :: thread in my other class, even if it is exactly the same as in my start class, it doesn't matter, I get this error when building error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function [...]\vc\include\functional 1124 1

The only way I was able to get around this error was to simply not declare the std::thread object in the last class, which is impossible, according to what I want it to execute ...

I am using VS2013, and my sources are:

stdafx.h

 #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include <Windows.h> #include <WinSock2.h> #include <WS2tcpip.h> #include <thread> #include <iostream> #include <vector> 

StreamServer.h

 #pragma once #define DEFAULT_BUFLEN 65535 #define DEFAULT_PORT "5649" class StreamServerClient { public: bool* terminate; //std::thread client; //If I comment this line out, it builds just fine. void DoNothing(); StreamServerClient(SOCKET clientSock, bool* ptTerm); StreamServerClient(); ~StreamServerClient(); }; class StreamServer { public: bool terminate; std::thread Listener; std::vector<StreamServerClient> clients; void CreateClient(SOCKET, bool*); void Listen(); StreamServer(); ~StreamServer(); }; 

StreamServer.cpp

 #include "stdafx.h" #include "StreamServer.h" StreamServerClient::StreamServerClient(SOCKET clientSock, bool* ptTerm) { terminate = ptTerm; //client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration } StreamServerClient::StreamServerClient() { *terminate = false; //client = std::thread(&StreamServerClient::DoNothing, this); //Same thing as the declaration } void StreamServerClient::DoNothing() { } StreamServerClient::~StreamServerClient() { } void StreamServer::Listen() { {...} do { clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate)); std::cout << "accepted a client!" << std::endl; } while (!terminate); } StreamServer::StreamServer() { terminate = false; Listener = std::thread(&StreamServer::Listen, this); Listener.detach(); } StreamServer::~StreamServer() { } 
+7
c ++ multithreading c ++ 11 visual-c ++ visual-studio-2013
source share
2 answers

Objects of type std::thread cannot be copied. It is best to just initialize the objects in the 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 skipped the default constructor (note that your version does not work because it tries to assign a value to dereference an uninitialized pointer) and instead adds a move constructor: when you click on std::vector<...> this constructor will be called when providing something that looks like temporary (i.e. something that is either temporary or similar to one, for example, using std::move() ).

+9
source share

The std::thread object cannot be copied. When this line is called:

 clients.push_back(StreamServerClient::StreamServerClient(accept(listenSock, NULL, NULL), &terminate)); 

The StreamServerClient object you StreamServerClient must be added to the clients vector, but the only way to do this is to copy it, because your StreamServer object StreamServer not have a specific move constructor. The default instance constructor for StreamServerClient , and what the default instance constructor in C ++ 11 does is invokes copy constructors for all data elements.

In this case, it calls the copy constructor of the std::thread data element, which is deleted.

The reason std::thread cannot be copied is because the std::thread object matches the thread of execution. You must reorganize your code, IMO. You could hack the move constructor for StreamServerClient , but I think there are cleaner solutions, for example, replacing std::thread pointer to std::thread and initializing the thread with a completely separate call.

Edit: In general, I would say that it is not wise to separate the new thread in the constructor of the object, because this is too subtle an operation. (This may fail, then you will have to deal with exceptions, etc.) Although, perhaps C ++ purists will disagree with me.

Edit: Had silly terminology.

+6
source share

All Articles