如何将模板函数的模板参数传递给函数内的Lambda表达式
问题分析与正确实现
你的代码存在两个关键问题,同时需要优化参数转发逻辑:
核心错误点
- 成员函数指针调用语法错误:指向类成员函数的指针不能用
c.f(...)调用,必须使用(c->*f)(...)的语法——这是C++中成员函数指针的标准调用方式。 - Lambda参数未传递:你定义的Lambda需要接收
f、c和args,但在std::make_unique<std::thread>时没有把这些参数传递给Lambda,会导致Lambda内部的参数未初始化,运行时直接崩溃。
参数转发的正确处理
因为你的run函数使用了转发引用(Args&&... args),目的是保留参数的左值/右值属性,所以需要在Lambda内部和线程构造时都正确转发参数:
实现方式一:复用原模板参数
template <typename C, typename F, typename... Args> void MyClass::run(F C::*f, C* c, Args&&... args) { td_ = std::make_unique<std::thread>( // Lambda参数使用Args&&,保留原参数的值类别 [](F C::*f, C* c, Args&&... args){ (c->*f)(std::forward<Args>(args)...); // 正确转发参数 }, f, c, std::forward<Args>(args)... // 将外部参数传递给Lambda ); }
实现方式二:用auto&&简化转发(C++14及以上)
如果你的编译器支持C++14或更高版本,用auto&&可以让Lambda自动推导参数类型,无需依赖外部模板参数,代码更简洁:
template <typename C, typename F, typename... Args> void MyClass::run(F C::*f, C* c, Args&&... args) { td_ = std::make_unique<std::thread>( [](F C::*f, C* c, auto&&... inner_args){ (c->*f)(std::forward<decltype(inner_args)>(inner_args)...); }, f, c, std::forward<Args>(args)... ); }
关键细节说明
std::forward<Args>(args)...:在传递参数给线程时,必须用std::forward保留原参数的左值/右值属性,避免不必要的拷贝或移动。- Lambda内部的
std::forward:确保传递给成员函数的参数和原调用时的值类别一致,比如原参数是右值时,成员函数能拿到右值,支持移动语义。
内容的提问来源于stack exchange,提问作者Yves
相关产品推荐
相关产品推荐

