0

我正在尝试使用 winSock 编写一个简单的客户端-服务器-应用程序,以更好地了解它是如何工作的。服务器应该能够支持多个客户端,因此每次有新客户端连接到服务器时,都会启动一个新线程来接收客户端消息。

我有一个结构,它存储有关已连接客户端的信息,例如 winSock SOCKET,因此我不必担心调用 winSock 的closesocket(...)函数,因为它将在我的ConnectedClient结构的析构函数中调用:

struct ConnectedClient
{
    SOCKET sock;
    bool disconnected;
    
    ConnectedClient(SOCKET&& sock)
        : sock(std::move(sock)), disconnected(false)
    {}
}

在服务器类中,我有一个std::vector包含所有连接的客户端并添加一个新连接的客户端,我调用我的函数AddClient。在这个函数中,我启动一个运行该函数的线程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();
    }
}

现在我的问题是:当调用 的构造函数时std::thread,为什么 (1) 编译和 (2) 抛出以下编译器错误

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

0 回答 0