Vector of elements containing std::threads

  • A+
Category:Languages

I've got a class Tester containing an std:thread object, and an std::vector of Tester. I understand that I can't copy threads, so the push_back is out of the question, but why emplace_back is not working? Where is the copy in my code?

#include <iostream> #include <thread> #include <vector> #include <functional> #include <unistd.h>  class Tester { public:     Tester(std::function<void(void)> func) :          th(func)     {     }      ~Tester()     {         th.join()     }  private:     std::thread th; };  std::vector<Tester> testers;  void InnerHelloWorld() {     std::cout << "Hello from the inner word!/n"; }  int main() {     std::cout << "Hello World!/n";      for(size_t i = 0 ; i < 4 ; i++)     {         testers.emplace_back(InnerHelloWorld);     }      sleep(1);      return 0; } 

 


Theres a couple of minor issues in your code

You missed the trailing semi-colon off of:

th.join() 

But importantly, you need to give your class a move constructor - the default one is fine:

Tester(Tester&&) = default; 

This is needed as when vectors resize themselves they need to move or copy their elements. A move constructor will generally be created for you but in your case having a custom destructor supresses it. See here.

This will let your code compile, but then it'll throw an exception at runtime. This is because you sometimes destruct from moved-from Testers which will call join on a moved from thread. Fortunately this is an easy fix:

~Tester()  {    if(th.joinable())        th.join();  } 

Full working code:

#include <iostream> #include <thread> #include <vector> #include <functional>  #include <unistd.h>  class Tester {   public:   Tester(std::function<void(void)> func) :      th(func)   {   }    ~Tester()   {     if(th.joinable())         th.join();   }    Tester(Tester&&) = default;    private:   std::thread th; };  std::vector<Tester> testers;  void InnerHelloWorld() {   std::cout << "Hello from the inner word!/n"; }  int main() {   std::cout << "Hello World!/n";    for(size_t i = 0 ; i < 4 ; i++)   {     testers.emplace_back(InnerHelloWorld);   }    sleep(1);    return 0; } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: