4

你能告诉 mw 下面的 boost::thread 程序有什么问题吗

#include<iostream>
#include<boost/thread/thread.hpp>

boost::mutex mutex;

class A
{
public:
A() : a(0) {}

void operator()()
{
          boost::mutex::scoped_lock lock(mutex);

}
private:
int a;

};

int main()
{
    boost::thread thr1(A());
    boost::thread thr2(A());
    thr1.join();
    thr2.join();

}

我收到错误消息:错误:在 'thr1' 中请求成员 'join',它是非类类型 'boost::thread()(A ( )())' BoostThread2.cpp:30:错误:请求对于'thr2'中的成员'join',它是非类类型'boost :: thread()(A()())'

4

2 回答 2

7

您偶然发现了被称为最令人烦恼的解析的奇妙事物。解决这个问题的最快方法是添加一组额外的括号:

boost::thread thr1((A()));

你也可以引入一个临时的:

A tmp1;
boost::thread thr1(tmp1);

在最令人头疼的解析中,您认为生成临时的东西被解析为好像它是一个不带参数的函数。然后它将 thr1 视为一个函数的原型,该函数接受一个参数(即前面提到的函数)并返回一个 boost::thread。

于 2010-05-15T05:10:23.157 回答
6

这是一个经典的 C++ 陷阱。thr1不是您认为的那样(线程对象)。它是一个将 A 的实例作为参数的函数的声明。将其括在括号中以强制执行预期的解释:

boost::thread thr1((A()));
boost::thread thr2((A()));

详细解释

在语法上,原始语法等价于:

boost::thread thr1(A);

为什么允许编译器忽略空括号?坦率地说,我不确定——我不是 C++ 语言专家——但我认为这与以下思路有关:A *a= A (*a),因此A *= A (*); 同样,A a= A (a),因此A= A ()

展望未来!

即将到来的 C++ 标准将把它作为其新初始化语法的副产品来解决:

boost::thread thr1{A()};
boost::thread thr2{A()};
于 2010-05-15T05:05:41.607 回答