Could you tell mw what is the problem with the below boost::thread program
#include<iostream>
#include<boost/thread/thread.hpp>
boost::mutex mutex;开发者_如何学C
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();
}
I get the error message: error: request for member 'join' in 'thr1', which is of non-class type 'boost::thread()(A ()())' BoostThread2.cpp:30: error: request for member 'join' in 'thr2', which is of non-class type 'boost::thread ()(A ()())'
You have stumbled on something wonderfully known as the most vexing parse. The quickest way to fix that is to add an extra set of parentheses:
boost::thread thr1((A()));
You can also introduce a temporary:
A tmp1;
boost::thread thr1(tmp1);
In the most vexing parse, what you think is generating a temporary is parsed as if it's a function taking no parameters. It then treats thr1 as a prototype to a function that takes a single parameter (which is the function mentioned previously) and returning a boost::thread.
This is a classic C++ trap. thr1
is not what you think it is (a thread object). It's the declaration of a function that takes an instance of A as a parameter. Wrap it in parentheses to force the intended interpretation:
boost::thread thr1((A()));
boost::thread thr2((A()));
The detailed explanation
Syntactically, the original syntax is equivalent to:
boost::thread thr1(A);
Why is the compiler allowed to ignore the empty parentheses? Frankly, I'm not sure — I'm not a C++ language expert — but I think it has to with the following train of thought: A *a
= A (*a)
, therefore A *
= A (*)
; likewise, A a
= A (a)
, therefore A
= A ()
.
Look to the future!
The upcoming C++ standard will fix this as a byproduct of its new initialisation syntax:
boost::thread thr1{A()};
boost::thread thr2{A()};
精彩评论