You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法使用自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:57:39