Reputation:
I am trying to create a vector of threads with the property of automatic join at destruction. Stroustrup suggests guarded_thread:
struct guarded_thread : std::thread {
using std::thread::thread;
~guarded_thread() { if (joinable()) join(); }
};
This guarded_thread works like charm:
void f() { std::cerr << "f();" << std::endl; }
int main() { guarded_thread gt(f); }
But only as long as I don't want to store a couple of these in a vector:
void f() { std::cerr << "f();" << std::endl; }
int main() { std::vector<guarded_thread> v; v.emplace_back(f); }
Actually emplace_back() or push_back() make the compiler emit a very long error message complaining about "type" not found in std::result_of but I don't understand why on earth would std::result_of be instantiated with guarded_thread() as a template parameter. Thread has a template constructor on my STL implementation:
template<typename _Callable, typename... _Args>
explicit
thread(_Callable&& __f, _Args&&... __args)
{
#ifdef GTHR_ACTIVE_PROXY
__asm ("" : : "r" (&pthread_create));
#endif
_M_start_thread(_M_make_routine(std::__bind_simple(
std::forward<_Callable>(__f),
std::forward<_Args>(__args)...)));
}
The problem is: somehow _Callable is substituted to guarded_thread but I don't understand why. Maybe the copy constructor tried to be called? How could it be fixed?
I tried two different compilers:
Roughly both complains about the same error.
Upvotes: 2
Views: 413
Reputation: 3295
Seems like guarded_thread
is missing a default move constructor and the copy constructor should be deleted.
Here is a working example.
guarded_thread(const guarded_thread&) = delete ;
guarded_thread(guarded_thread&&) = default ;
Note : Your code was calling a deleted function i.e. std::thread
copy constructor and did not provide a move constructor either.
Upvotes: 4