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

C++中CoffeeShop类成员函数传递给user类对象的编译错误问询

错误原因分析

编译错误的核心是非静态成员函数无法直接赋值给std::function。CoffeeShop::Make_Coffee是非静态成员函数,它的类型是void (CoffeeShop::*)(std::string),这类函数必须依附于具体的CoffeeShop对象实例才能调用(隐含this指针参数),而user类中的fun是std::function<void(std::string)>,两者类型不匹配,无法直接赋值。

解决方案

有两种常用方法可以解决这个类型不匹配问题,同时保证用户排队依次处理的需求:

方法1:使用std::bind绑定对象实例

通过std::bind将CoffeeShop的当前实例(this)和成员函数绑定,生成一个符合std::function<void(std::string)>类型的可调用对象:

修改CoffeeShop::assign函数中的赋值代码:

void assign() {
    user a;
    // 绑定当前CoffeeShop实例和Make_Coffee函数
    a.fun = std::bind(&CoffeeShop::Make_Coffee, this, std::placeholders::_1);
    a.name = "amr kamal";
    thread th1(&user::order_coffee, a);

    user b;
    b.fun = a.fun; // 可以直接拷贝已绑定的function
    b.name = "hadeer";
    thread th2(&user::order_coffee, b);

    th1.join();
    th2.join();
}

方法2:使用Lambda表达式捕获对象实例

用Lambda表达式捕获当前CoffeeShop实例,直接在Lambda内部调用Make_Coffee函数,这种方式更直观:

void assign() {
    user a;
    // Lambda捕获当前CoffeeShop实例,调用Make_Coffee
    a.fun = [this](std::string name) {
        this->Make_Coffee(name);
    };
    a.name = "amr kamal";
    thread th1(&user::order_coffee, a);

    user b;
    b.fun = a.fun;
    b.name = "hadeer";
    thread th2(&user::order_coffee, b);

    th1.join();
    th2.join();
}
额外优化建议
  1. 移除多余的lock.unlock():std::unique_lock会在析构时自动释放锁,手动调用unlock()不仅多余,还可能导致逻辑错误(比如后续代码意外使用已解锁的锁),直接删除该行即可。
  2. 线程传参优化:原代码中thread th1(&user::order_coffee, a)会拷贝user对象,如果希望操作原对象,可以改为thread th1(&user::order_coffee, std::ref(a)),但当前场景下拷贝不影响功能。

修改后的完整CoffeeShop::Make_Coffee函数:

void Make_Coffee(string name) {
    cout << "in queue: " << name << endl;
    unique_lock<mutex> lock(mtx);
    cout << "welcome,order in process, " << name << endl;
    this_thread::sleep_for(chrono::seconds(4));
    cout << "good bye, " << name << endl;
}

内容的提问来源于stack exchange,提问作者user7179690

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:16:10