C++中最令人头痛的语法解析:most vexing parse
我们先来看一个例子:std::thread类。
如同大多数C++标准库一样,std::thread可以用可调用(callable)类型构造,将带有函数调用符类型的实例传入std::thread类中,替换默认的构造函数。
因此:我们可以写出如下的代码:
class background_task
{
public:
void operator()() const
{
do_something();
do_something_else();
}
};
// 注意下面两段代码:可以正常运行
background_task f;
std::thread my_thread(f);
注意:如果你传递了一个临时变量,而不是一个命名的变量;C++编译器会将其解析为函数声明,而不是类型对象的定义。
/*
* background_task f;
* std::thread my_thread(f);
* 当这两条语句简化成下面这一条语句的时候,会产生非预期的效果
*/
std::thread my_thread(background_task());
这里相当与声明了一个名为my_thread的函数,这个函数带有一个参数(函数指针指向没有参数并返回background_task对象的函数),返回一个std::thread对象的函数,而非启动了一个线程。
使用下面的方式可以解决most vexing parse问题:
- std::thread my_thread((background_task()));
- std::thread my_thread{background_task()};
- 使用lambda表达式避免该问题,示例如下:
std::thread my_thread([]{
do_something();
do_something_else();
});
近期评论