2014-12-18 5 views
5

Chcę przenieść obiekt kontenerowy std::map na inny. W najprostszej postaci:Jak dołączyć/skopiować obiekt kontenerowy STL do innego obiektu, gdy jego wartość nie jest możliwa do skopiowania, np. std :: wątek

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

jednak daje stronę error:

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

Jak to osiągnąć?

+1

Cóż, nie można skopiować wątki. Mam tylko jedną sugestię: 'map >>' (lub 'map >>", w zależności od tego, która opcja wydaje się bardziej odpowiednia). – Wintermute

+0

To, o co prosisz, nie ma większego sensu - co to znaczy skopiować wątek? Czy chcesz zamiast tego przenieść? – Cameron

+0

@Cameron, tak właściwie to jest ruch. Następnie uruchomię 'm2.clear()'. – iammilind

Odpowiedz

11

std::thread nie jest kopia constructible, będziesz musiał użyć iterator, który umożliwia ruchy:

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

std::make_move_iterator zwraca iterator specjalistycznej klasa std::move_iterator, której członkowie dostępu (operator*() i operator->()) zwracają odwołania do wartości r, w przeciwieństwie do wbudowanych iteratorów zwracających wartości l. map::insert() deleguje swoją operację do map::emplace(), gdzie przekazuje argument do typu elementu.

Wywoływano konstruktorów kopiowania wątków, ponieważ obiekty zwracane z wbudowanych iteratorów były przesyłane jako lwartość i tym samym kopiowane.

1

Ogólne rozwiązanie: przenieś.

Jednak podczas gdy std::move() może przesuwać pojedynczą wartość, nie może przesuwać zakresu wartości. Musisz napisać pętlę:

for (auto&& pair : m1) m2[pair.first] = std::move(pair.second) 
2

Nie sądzę, że będziesz w stanie wstawić szereg elementów, które są ruchome. Powinieneś być w stanie std::move() poszczególne elementy, ale:

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

Wręcz przeciwnie, istnieje 'std :: make_move_iterator'. Ale oczywiście nie jest semantycznie taka sama jak kopia. – Cameron

3

je przenieść za pomocą iteratorów ruch:

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

Tylko dla kompletności, jest mało znana wersja std::move w <algorithm> że jest podobny wzór do std::copy.

Więc można napisać to:

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

reference here

Powiązane problemy