C++ 初始化std::thread触发static assertion failed的解决方法
问题根因
你碰到的这个静态断言报错,核心原因是给std::thread传的参数根本不是可调用的线程入口,本质是踩中了C++经典的**最令人头疼解析(Most Vexing Parse)语法坑:
你在代码里写的AppliMsgWait(),编译器的解析逻辑根本不是“把AppliMsgWait这个函数当成线程入口传进去”,而是把它识别成当场调用AppliMsgWait函数、拿这个函数的int返回值当参数传给thread构造函数**。一个int值显然没法被当成可调用对象执行,完全不符合std::thread的参数要求,编译阶段就会直接触发这个静态断言。
对比你代码里写对的那行线程创建逻辑:std::thread RadMgrThd(&RadMgr::RadMgrWaitEvt,&RadioManager);——这行没有当场调用成员函数,只是传递了成员函数指针和要绑定的对象实例,因此可以正常通过编译。
具体修复方式
- 删掉所有传给std::thread的函数名后面的调用圆括号,直接传函数名即可。C++语法里函数名本身会自动退化为函数指针,也可以写
&函数名的取地址形式,两种写法都能被std::thread正常识别,核心是不能加圆括号触发“当场调用函数”的解析逻辑。 - 原错误代码段:
std::thread AppliWaitThd(AppliMsgWait()); std::thread AppliSNMPWaitThd(AppliSNMPWait()); if (InitRole==masterRole) { std::thread GesCanSrvThd(GesCanSrvRecvMsg()); std::thread GesCanSlotThd(GesCanSlotPeriod()); } - 修改为正确写法:
std::thread AppliWaitThd(AppliMsgWait); std::thread AppliSNMPWaitThd(AppliSNMPWait); if (InitRole==masterRole) { std::thread GesCanSrvThd(GesCanSrvRecvMsg); std::thread GesCanSlotThd(GesCanSlotPeriod); } - 补充优化点:
AppliMsgWait这类内部写了永久while(1)循环的线程函数,永远执行不到最后的return 1;语句,可以把函数返回值从int改成void,语义更准确,也能避免产生无意义的返回值编译告警。
内容的提问来源于stack exchange,提问作者user15832441
相关产品推荐
相关产品推荐

