user1189258
user1189258

Reputation:

std::vector of std::thread descendants

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

Answers (1)

a_pradhan
a_pradhan

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

Related Questions