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(); }
额外优化建议
- 移除多余的
lock.unlock():std::unique_lock会在析构时自动释放锁,手动调用unlock()不仅多余,还可能导致逻辑错误(比如后续代码意外使用已解锁的锁),直接删除该行即可。 - 线程传参优化:原代码中
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
相关产品推荐
相关产品推荐

