C++中如何将参数包通过void指针传递给线程入口函数?
解决方案:传递参数包到静态线程入口函数
要解决参数包通过void*传递的问题,核心思路是把参数包打包成一个可通过指针传递的容器(比如std::tuple),在堆上分配内存存储这个容器,传递其地址到静态线程函数,最后在函数内解包调用目标函数并清理内存。
以下是修改后的完整代码:
#include <functional> #include <iostream> #include <tuple> template <typename... Ts> class SomeClass { public: std::function<bool(Ts...)> some_func; void run(Ts... args) { this->some_func(args...); // 打包参数包为tuple,分配堆内存存储(避免栈内存提前销毁) auto* args_tuple = new std::tuple<Ts...>(std::forward<Ts>(args)...); // 传递function指针和tuple指针到静态线程函数 this->thread_run((void*)&this->some_func, (void*)args_tuple); } static void thread_run(void* func_ptr, void* args_ptr) { // 转换回原类型 auto thread_func = *static_cast<std::function<bool(Ts...)>*>(func_ptr); auto* args_tuple = static_cast<std::tuple<Ts...>*>(args_ptr); // 解包tuple并调用目标函数 std::apply(thread_func, *args_tuple); // 释放堆内存,避免泄漏 delete args_tuple; } }; int main() { SomeClass<int, int> a; a.some_func = [](int x, int y) { std::cout << "Arguments: " << x << " " << y << std::endl; return x > y; }; a.run(2, 3); return 0; }
关键细节说明
- 打包参数:用
std::tuple<Ts...>打包参数包,搭配std::forward保持参数的左值/右值特性,减少不必要的拷贝。 - 堆内存分配:线程可能在
run函数返回后才执行,栈上的tuple会被销毁,因此必须用new分配堆内存存储参数。 - 解包调用:
std::apply可以自动将tuple中的元素展开为函数的参数列表,完美适配参数包的调用需求。 - 内存清理:线程函数执行完毕后必须
deletetuple指针,否则会造成内存泄漏。如果线程库支持结束回调,也可以把清理逻辑放到回调中。
内容的提问来源于stack exchange,提问作者Gizmo
相关产品推荐
相关产品推荐

