为何无法使用自定义UDPClient类初始化std::thread线程?
问题分析与解决:线程调用UDPClient类方法的编译错误
原始代码
class UDPClient { private: boost::asio::io_service& io_service_; udp::socket socket_; udp::endpoint endpoint_; public: UDPClient(boost::asio::io_service& io_service, std::string host, std::string port) : io_service_(io_service), socket_(io_service, udp::endpoint(udp::v4(), 0)) { udp::resolver resolver(io_service_); udp::resolver::query query(udp::v4(), host, port); udp::resolver::iterator iter = resolver.resolve(query); endpoint_ = *iter; } void send(std::vector<unsigned char> msg) { socket_.send_to(boost::asio::buffer(msg, msg.size()), endpoint_); std::cout << "sent" << std::endl; } std::vector<unsigned char> receive() { std::vector<unsigned char> receive_data; receive_data.resize(65495); udp::endpoint sender; size_t len = socket_.receive_from(boost::asio::buffer(receive_data), sender); receive_data.resize(len); return receive_data; } }; void getMsg(UDPClient client) { while (true) { auto x = client.receive(); cout << "received "<< std::hex << x[0] << endl; } } int main() { boost::asio::io_service io_service; UDPClient client(io_service, std::string("localhost"), std::string("5213")); std::thread thr1(getMsg, client); thr1.join(); }
首次编译错误
C2661 'std::tuple<void (__cdecl *)(UDPClient),UDPClient>::tuple': no overloaded function takes 2 arguments
C2672 'invoke': no matching overloaded function found
修改后的代码(尝试指针传递)
void getMsg(UDPClient *client) { while (true) { auto x = client->receive(); cout << "received "<< std::hex << x[0] << endl; } } int main() { boost::asio::io_service io_service; UDPClient client(io_service, std::string("localhost"), std::string("5213")); std::thread thr1(getMsg, std::ref(client)); thr1.join(); }
修改后仍存在的错误
Error C2672 'invoke': no matching overloaded function found
问题根源与解决方案
核心问题1:UDPClient无法拷贝
UDPClient类包含boost::asio::io_service&引用成员和udp::socket成员,这两类都不支持拷贝构造。第一次按值传递UDPClient client时,线程构造函数会尝试拷贝client,直接触发编译错误。
核心问题2:指针传递时参数不匹配
修改为指针参数后,用std::ref(client)传递了引用,导致线程函数期望UDPClient*但实际传入std::reference_wrapper<UDPClient>,类型不匹配,所以报错。
两种正确解决方式
方式1:传递对象指针
直接传递对象地址,与线程函数的指针参数匹配:
void getMsg(UDPClient *client) { while (true) { auto x = client->receive(); std::cout << "received "<< std::hex << x[0] << std::endl; } } int main() { boost::asio::io_service io_service; UDPClient client(io_service, std::string("localhost"), std::string("5213")); // 传递对象地址,参数类型匹配 std::thread thr1(getMsg, &client); thr1.join(); }
方式2:传递对象引用
修改线程函数参数为引用类型,同时用std::ref传递引用:
// 参数改为UDPClient引用 void getMsg(UDPClient& client) { while (true) { auto x = client.receive(); std::cout << "received "<< std::hex << x[0] << std::endl; } } int main() { boost::asio::io_service io_service; UDPClient client(io_service, std::string("localhost"), std::string("5213")); // 用std::ref传递引用 std::thread thr1(getMsg, std::ref(client)); thr1.join(); }
额外注意点
- 确保
cout和endl使用完整命名空间std::,或者局部添加using namespace std;(不推荐全局使用)。 - 无限循环
while(true)需补充退出逻辑,避免程序无法正常终止。
内容的提问来源于stack exchange,提问作者disssbalance
相关产品推荐
相关产品推荐

