I'm trying to code a simple client-server-application with winSock to better understand how it all works. The server should be able to support multiple clients and therefore starts a new thread for receiving client messages each time a new client connects to the server.
I have a struct that stores information about the connected client like the winSock SOCKET
so I don't have to worry about calling winSock's closesocket(...)
function as it will be called in the destructor of my ConnectedClient
struct:
struct ConnectedClient
{
SOCKET sock;
bool disconnected;
ConnectedClient(SOCKET&& sock)
: sock(std::move(sock)), disconnected(false)
{}
}
In the server class I have a std::vector
which holds all connected clients and to add a newly connected client I call my function AddClient
. In this function I start a thread that runs the function ClientRcv
:
class Server
{
std::vector<std::unique_ptr<ConnectedClient>> clients;
void ClientRcv(const std::unique_ptr<ConnectedClient>& c)
{
//...
c->disconnected = true;
}
void AddClient(SOCKET&& clientSocket)
{
std::unique_ptr<ConnectedClient> cc(std::make_unique<ConnectedClient>(std::move(clientSocket)));
clients.push_back(std::move(cc));
//(1) this works
std::thread rcvThread([this]() { ClientRcv(clients.back()); });
//(2) this doesn't
//std::thread rcvThread(&Server::ClientRcv, this, clients.back());
rcvThread.detach();
}
}
Now my question is this:
When calling the constructor of std::thread
, why does (1) compile and (2) throw following compiler error
Error C2664 'std::tuple<void (__cdecl Server::* )(const std::unique_ptr<Server::ConnectedClient,std::default_delete<Server::ConnectedClient>> &),Server *,std::unique_ptr<Server::ConnectedClient,std::default_delete<Server::ConnectedClient>>>::tuple(std::tuple<void (__cdecl Server::* )(const std::unique_ptr<Server::ConnectedClient,std::default_delete<Server::ConnectedClient>> &),Server *,std::unique_ptr<Server::ConnectedClient,std::default_delete<Server::ConnectedClient>>> &&)': cannot convert argument 1 from '_Ty' to 'std::allocator_arg_t'