Reputation: 7235
I am reading documents about c++11 multi-threads, and met this example for std::thread
.
Code:
void thread_task(int n) {
...
}
int main(int argc, const char *argv[])
{
std::thread threads[5];
for (int i = 0; i < 5; i++) {
threads[i] = std::thread(thread_task, i + 1);
}
return 0;
}
I do not understand threads[i] = std::thread(thread_task, i + 1);
. Is the std::thread
a static function call, and returns a reference for std::thread object? Sounds inconceivable, but seems to be what the code say.
Because I would write it like this:
std::thread *threads[5];
for (int i = 0; i < 5; i++) {
threads[i] = new std::thread(thread_task, i + 1);
}
Thanks.
Upvotes: 1
Views: 223
Reputation: 26050
Let's go through exactly what is happening:
std::thread threads[5];
This creates an array of 5 std::thread
objects, which are default constructed. Currently they represent "not a thread" as this is the state default construction leaves them in.
for (int i = 0; i < 5; i++) {
threads[i] = std::thread(thread_task, i + 1);
}
This uses the move form of operator=
. Because threads are not copyable, only moveable, thread& operator=(thread&& t)
is defined while thread& operator=(const thread& t)
is not. This assigns the thread object in threads[i]
to the newly constructed std::thread(thread_task, i + 1);
.
There is no reason to use an array of pointers here. It adds nothing but the possibility for memory leaks.
Upvotes: 13
Reputation: 985
This:
std::thread(thread_task, i + 1)
is a call to the std::thread constructor, which creates a new thread object and passes it a pointer to the thread_task function, which itself is called with i+1 as parameter.
The assignment is a move assignment (because the right hand side refers to an anonymous object), not a copy assignment. Note that the std::thread copy constructor and copy assignment operator are deleted.
This is actually a cleaner way than using pointers, because the std::thread objects will be destructed automatically when the threads array goes out of scope.
Upvotes: 2
Reputation: 56873
The default constructor of std::thread
creates an instance that does not represent a thread. The assignment is a move-assignment, since copies are also not allowed. It moves the real instance created by std::thread(thread_task, i + 1);
into the array.
Upvotes: 2
Reputation: 254531
Is the
std::thread
a static function call, and returns a reference forstd::thread
object?
No, it's creating a temporary thread object; just as int(42)
creates a temporary integer. The assignment moves that into the array, since threads are movable and temporaries can be moved from.
Because I would write it like this:
You're introducing dynamic allocation, an extra level of indirection, and memory leaks (unless you also add code to delete them when you're finished) for no good reason.
Upvotes: 2