为何编译std::thread仿函数时需要额外添加括号?
为什么
std::thread初始化时加额外括号能解决编译错误? 这其实是C++里大名鼎鼎的**最令人头疼的解析(Most Vexing Parse)**在搞鬼,我来给你拆解清楚:
1. 编译器对原代码的误解
你写的这行代码:
thread threadObj( MyThread() );
在编译器眼里,它不是在创建一个std::thread对象,而是被解析成了一个函数声明:
- 函数名:
threadObj - 返回类型:
thread(也就是std::thread) - 参数:一个指向“无参数、返回
MyThread类型的函数”的指针
说白了,编译器把MyThread()当成了函数类型的声明,而不是临时创建一个MyThread对象。这时候threadObj是个函数名,根本不是std::thread类的实例,后面调用threadObj.join()自然会报错“表达式必须具有类类型”——函数哪来的成员函数呢?
2. 加额外括号为什么能解决问题?
当你改成:
thread threadObj( (MyThread()) );
外层的括号把MyThread()包裹成了一个表达式。根据C++的语法规则,括号包裹的表达式不可能被解析成函数声明的一部分,编译器这时候才会明白:哦,原来你是要创建一个MyThread临时对象,然后把它传给std::thread的构造函数。
这样threadObj就真的变成了std::thread类的实例,调用join()自然就没问题了。
额外的解决思路
除了加括号,还有几种方式也能避开这个解析陷阱:
- 用列表初始化语法:
thread threadObj{ MyThread() }; - 先显式创建
MyThread对象:MyThread t; thread threadObj(t); - 用统一初始化的花括号:
thread threadObj( MyThread{} );
内容的提问来源于stack exchange,提问作者OopsUser
相关产品推荐
相关产品推荐

