Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to append/copy an STL container object to another object when its value is not copy constructible e.g. std::thread

I want to move an std::map container object to another. In simplest form:

#include<map>
#include<thread>
#include<vector>
using namespace std;

int main ()
{
  map<void*, vector<thread>> m1, m2; 
  // m1 is updated 

  m1.insert(m2.begin(), m2.end());  // <--- problem here
  m2.clear();  // not required anymore
}

However it gives a page of error:

error: use of deleted function ‘std::thread::thread(const std::thread&)’

How to accomplish this?

like image 640
iammilind Avatar asked Dec 18 '14 23:12

iammilind


2 Answers

std::thread is not copy-constructible, you'll have to use an iterator that allows moves:

m1.insert(std::make_move_iterator(m2.begin()),
          std::make_move_iterator(m2.end());

std::make_move_iterator returns a specialized iterator class std::move_iterator whose access members (operator*() and operator->()) return references to rvalues unlike the built in iterators that return lvalues. map::insert() delegates its operation to map::emplace() where it forwards the argument into the element type.

Your threads' copy-constructors were being called because the objects returned from the built-in iterators were being forwarded as lvalues and thus copied.

like image 129
David G Avatar answered Oct 04 '22 20:10

David G


Just for completeness, there is a little-known version of std::move in <algorithm> that follows a similar pattern to std::copy.

So you can write this:

move(begin(m2), end(m2), inserter(m1, begin(m1)));
m2.clear();

reference here

like image 32
Richard Hodges Avatar answered Oct 04 '22 20:10

Richard Hodges