如何在模板函数中调用C++成员函数?(shared_ptr多线程场景)
正确调用带参数成员函数的后台线程模板实现
问题描述
尝试将类的std::shared_ptr传入run模板函数,在后台线程中执行带int参数的成员函数,但不清楚如何正确调用传入的成员函数指针。
现有代码
class MyA { public: MyA() = default; void func(int) { /* ... */ }; }; class MyB { public: MyB() = default; void func2(int) { /* ... */ }; }; auto myA = std::make_shared<MyA>(); auto myB = std::make_shared<MyB>(); run(myA, &MyA::func, 1, 5); run(myB, &MyB::func2, 1, 3);
当前错误的run函数实现
template <typename C, typename F> void run(std::shared_ptr<C> c, F f, int a, int b) { std::thread([&c, &f, a, b]() { while (true) { // 此处写法错误,不知如何调用传入的成员函数 c.f(a); std::this_thread::sleep_for(std::chrono::seconds(b)); } }).detach(); }
解决方案
要正确实现,需注意两个核心要点:
- 成员函数指针的调用语法:必须通过对象指针调用,且要注意运算符优先级,需用括号包裹指针与函数指针的绑定
- 线程变量捕获方式:不能引用捕获
std::shared_ptr和成员函数指针,线程detach后原变量可能销毁,会导致悬垂引用,必须值捕获
修正后的run函数实现:
#include <memory> #include <thread> #include <chrono> template <typename C, typename F> void run(std::shared_ptr<C> c, F f, int a, int b) { // 值捕获变量,避免线程detach后出现悬垂引用 std::thread([c, f, a, b]() { while (true) { // 正确调用成员函数指针:(对象指针->*成员函数指针)(参数) // 必须加括号,因为->*优先级低于函数调用 (c->*f)(a); std::this_thread::sleep_for(std::chrono::seconds(b)); } }).detach(); }
补充说明
- 运算符优先级:
->*的优先级低于函数调用(),如果不加括号,编译器会错误解析为c->*(f(a)),导致编译失败 - 线程安全:如果成员函数会修改类的成员变量,需要添加
std::mutex等同步机制保证线程安全 - 对象生命周期:需确保
shared_ptr指向的对象生命周期覆盖线程运行时间,避免线程运行时对象被销毁导致未定义行为
内容的提问来源于stack exchange,提问作者Ender
相关产品推荐
相关产品推荐

