C++11线程问题:非静态成员函数非法调用——GCC5.1.0正常GCC7.3.1报错
GCC 7编译std::thread调用非静态成员函数报错的解决方法
我来帮你搞定这个跨编译器版本的问题~
你这段代码在旧版TDM-GCC(GCC 5.1.0)的Windows 8/10环境下能正常编译运行,但升级到GCC 7就报错,核心原因是GCC 7对C++标准的遵循更严格,而旧版编译器的参数推导规则比较宽松。
先贴出你的代码方便参考:
// 创建类实例 MC_THREAD MTHR; // 在类中设置一些值 MTHR.setup_mc_thread("com6", &es); // 创建线程运行非静态成员函数 std::thread MCTHR(MC_THREAD::start_mc_thread, std::ref(MTHR)); // 函数定义 void MC_THREAD::start_mc_thread(){ while(1){ //do_stuff } }
问题根源
非静态成员函数必须绑定一个类实例才能调用,旧版GCC允许你省略成员函数指针的&符号,并且对参数匹配的检查不够严格;但GCC 7严格遵循C++标准,要求必须显式指定成员函数指针,同时确保参数传递的方式符合标准规范。
解决方案
方案1:用Lambda表达式包装(最推荐,兼容性最好)
Lambda可以直接捕获类实例,然后调用成员函数,写法直观,完全避免编译器版本的兼容性问题:
std::thread MCTHR([&MTHR]() { MTHR.start_mc_thread(); });
这里用引用捕获MTHR,确保线程里操作的是同一个实例,注意要保证MTHR的生命周期长于线程,避免出现悬空引用的问题。
方案2:显式传递成员函数指针
如果你想保留原来的写法,只需要给成员函数加上&符号,显式生成成员函数指针即可:
std::thread MCTHR(&MC_THREAD::start_mc_thread, std::ref(MTHR));
这样GCC 7就能正确识别成员函数的类型,并且正确绑定实例来调用函数。
内容的提问来源于stack exchange,提问作者Person512384
相关产品推荐
相关产品推荐

