Understanding std::thread constructor call with member function that takes parameters

169 Views Asked by At

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'
0

There are 0 best solutions below