Reputation: 560
I'm trying to create a vector of threads that perform a search. This is the important stuff from my SearchThread
class.
class SearchThread {
explicit SearchThread(int t_id) {
id = t_id;
run = true;
thread = std::jthread([&]{
while(run){
{
std::unique_lock lock(mtx);
cnd_var.wait(lock, [&] { return !run; });
if(!run) { return; }
}
Search();
}
});
}
void Search();
int id;
bool run;
std::jthread thread;
std::condition_variable cnd_var;
std::mutex mtx;
}
And i'm attempting to construct them like this.
std::vector<SearchThread> search_threads;
for (int t_id = 0; t_id < num_threads; t_id++) {
search_threads.emplace_back(t_id);
}
The error i'm getting is no matching function for call to 'construct_at'
. The issue i believe is with std::mutex
and std::conditional_variable
. I can have the mutex and conditional variable declared as pointers and then construct them on the heap in the class constructor, however that seems very ugly to me.
I guess my question is, why am i not allowed to do it like this, and is there a way around it?
Upvotes: 3
Views: 968
Reputation: 118445
std::mutex
is not copyable. Its copy constructor is deleted. "Copying a mutex" makes no logical sense. If the mutex is locked, what does that mean? Is the copy-constructed mutex is also locked? If so, who locked it? Who gets to unlock it?
This makes the SearchThread
class also uncopyable, and have a deleted copy constructor. Since one of its members is an uncopyable std::mutex
, that pretty much puts a kibosh on copy-ability of a SearchThread
, too.
std::vector
requires its contents to be copyable. One of std::vector
's proud achievements is that it will automatically copy the values in the vector, as needed, when it grows. This requires its contents to be copyable. SearchThread
is not copyable. You cannot put it into a vector. It doesn't matter how you try to put it, emplace_back
, or some other way. reserve()
won't help you. A std::vector
must contain a copyable class, there is no workaround for that.
Your options are:
Provide a user-defined copy constructor for your SearchThread
, that implements whatever it means for a SearchThread
to be copy-constructed from another instance of SearchThread
. Perhaps its sufficient to copy all of its other members, and just have the copy-constructed SearchThread
default-construct its mutex. You also have to provide a user-defined assignment operator as well. Or implement user-defined move constructor and assignment operator. The bottom line is: somehow make your SearchThread
copyable/movable/assignable.
Use some other container that does not require a copyable object, like std::list
perhaps.
Upvotes: 3