我正在尝试使用 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'