2014-12-18 7 views
5

Ich möchte verschieben ein std::map Container Objekt zu einem anderen. In einfachsten Form:Wie ein STL-Container-Objekt an ein anderes Objekt angehängt/kopiert wird, wenn sein Wert nicht kopierbar ist, z. std :: thread

#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 
} 

jedoch eine Seite von error gibt:

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

Wie dies zu erreichen?

+1

Nun, man die Fäden nicht kopieren können. Der einzige Vorschlag, den ich habe, ist ein 'map >>' (oder eine 'map >>', je nachdem, was passender scheint). – Wintermute

+0

Was du verlangst macht keinen Sinn - was bedeutet es, einen Thread zu kopieren? Möchten Sie es stattdessen verschieben? – Cameron

+0

@Cameron, ja eigentlich ist es Bewegung. Danach würde ich 'm2.clear()' ausführen. – iammilind

Antwort

11

std::thread nicht kopier konstruierbar, werden Sie einen Iterator, der erlaubt, sich Bewegungen verwenden müssen:

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

std::make_move_iterator gibt eine spezielle Iterator Klasse std::move_iterator, deren Zugriffsmember (operator*() und operator->()) Verweise auf rvalues ​​im Gegensatz zu den integrierten Iteratoren zurückgeben, die lvalues ​​zurückgeben. map::insert() delegiert seine Operation an map::emplace(), wo es das Argument in den Elementtyp weiterleitet.

Die Copy-Konstruktoren Ihrer Threads wurden aufgerufen, da die von den integrierten Iteratoren zurückgegebenen Objekte als lvalues ​​ weitergeleitet und somit kopiert wurden.

1

Die allgemeine Lösung: verschieben Sie es.

Während jedoch std::move() einen einzelnen Wert verschieben kann, kann er keinen Wertebereich verschieben. Sie müssen eine Schleife schreiben:

2

Ich glaube nicht, dass Sie eine Reihe von Elementen einfügen können, die nur beweglich sind. Sie sollten die einzelnen Elemente std::move() der Lage sein, aber:

for (auto& element: m2) { 
    m1.emplace(element.first, std::move(element.second)); 
} 
+0

Im Gegenteil, es gibt 'std :: make_move_iterator'. Aber es ist natürlich nicht semantisch dasselbe wie eine Kopie. – Cameron

3

sie bewegen, bewegen Iteratoren mit:

m1.insert(make_move_iterator(begin(m2)), make_move_iterator(end(m2))); 
5

Nur der Vollständigkeit halber gibt es eine wenig bekannte Version von std::move in <algorithm>, die ein ähnliches Muster wie std::copy folgt.

So können Sie schreiben:

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

reference here