Reputation:
I was reading concurrency in action and came up with this piece of code. However, i dont quite understand why line<1> is syntax valid. Also, how the order got determined? is it possible to put std::thread t(&my_x, &X::do_lengthy_work);
instead? how many inputs can take based on the code over here?
class X
{
public:
void do_lengthy_work();
};
X my_x;
std::thread t(&X::do_lengthy_work,&my_x); //<1> the bood says This code will invoke my_x.do_lengthy_work() on the new thread, because the address of my_x is supplied as the object pointer
Upvotes: 0
Views: 1556
Reputation: 73366
Excellent book about the topic !
std::thread t(...);
creates a thread object t. The first argument of the constructor must be either the adress of a function, or an executable class (i.e. a class with operator() defined).
For ordinary functions like void f(){... }
, it would be sufficient to give its name as first argument f
. For member function, you have to give its full name, so here: X::do_lengthy work
. But for getting the pointer to the mbmer function an explicit &
is required (see C++11 standard, section 5.3.1, pt 4).
The arguments following the first arguments will be given to the function when the thread starts and wants to execute it. In the specific case of member functions, the very first argument will be used to say on which object the function has to be executed.
So roughly speaking thread(&class::member_function, arg1, arg2, ... arg n)
will call arg1.member_function (arg2, .... arg n)
.
Upvotes: 2
Reputation: 23793
I think that you are confused by the syntax here.
This is just a constructor call for an object of type std::thread
named t
(so the arguments order did not "get determined", it is defined by the constructor signature).
Two parameters are expected by this constructor :
1) A callable : &X::do_lengthy_work
, as a pointer to a member function, is a Callable.
2) The arguments expected by the Callable : a member function always has an implicit this
argument of type (const) X*
: this is why here you pass &my_x
, the address of the object on which the Callable will be called.
If you add an argument to do_lengthy_work
, then you need to specify it when you construct the thread as well :
class X
{
public:
void do_lengthy_work(int i) {}
};
int main() {
X my_x;
std::thread t(&X::do_lengthy_work,&my_x, 2);
^^^^
}
Upvotes: 3
Reputation: 44238
Also, how the order got determined? is it possible to put std::thread t(&my_x, &X::do_lengthy_work); instead?
As with any other c++ function order determined by function signature, in this case std::thread
constructor signature:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
from std::thread documentation
As you can see that Function
is the first parameter and parameters follow (if any). So you cannot put pointer to class before pointer to method.
Upvotes: 2