Reputation: 77
Why can't I call my vector of threads from the destructor? Is there some rule for using destructors?
void p ()
{
std::cout << "thread running " << std::endl;
}
class VecThreads // Error: In instantiation of member function 'std::__1::vector<std::__1::thread, std::__1::allocator<std::__1::thread> >::vector' requested here
{
public:
std::vector<std::thread> threads;
VecThreads() {
threads.push_back(std::thread(p));
}
~VecThreads()
{
threads[0].join();
}
};
int main(int argc, const char * argv[]) {
VecThreads h = VecThreads();
//h.threads[0].join(); // delete deconstructor and use this works fine
return 0;
}
The error I get:
Calling a private constructor of class 'std::__1::thread'
Upvotes: 3
Views: 355
Reputation: 24788
The problem is in:
VecThreads h = VecThreads();
VecThreads
has no move constructor, its generation is disabled (i.e., not declared) because it has a user-defined destructor. Therefore, the statement above calls VecThreads
's copy constructor.
VecThreads
contains a data member of type std::vector<std::thread>
– which isn't copyable since an std::thread
object is not copyable. Even though an std::vector<std::thread>
is not copyable, it is movable, so a move constructor would, in principle, do the trick. You can explicitly enable the generation of the move constructor by adding the following inside VecThreads
's definition:
VecThreads(VecThreads&&) = default;
Your original code does compile since C++17 without modification thanks to mandatory copy elision.
Upvotes: 3