Posso atribuir o conteúdo de um std :: map a outro std :: map?

É possível inserir o conteúdo de um std :: map temporáriotemp em outro std :: mapm usando a semântica de movimentação, para que os valores do temporário não sejam copiados e reutilizados?

Digamos que alguém tenha:

std::map<int, Data> temp;
std::map<int, Data> m;

Uma maneira de copiar valores detemp para dentrom é:

m.insert(temp.begin(),temp.end());

Como possomover atemp elementos emm, em vez de copiar?

questionAnswers(3)

Ainda não tentei, mas achostd :: move_iterator deve ajudar aqui:

 using it = std::map<int, Data>::iterator;
 using mv = std::move_iterator <it>;

 m.insert(mv(temp.begin()),mv(temp.end()));
 Gabriel13 de fev de 2014 14:00
eu também não sabia :-)
 Richard Vock12 de fev de 2014 21:45
Ufa ... Obrigado por isso do meu lado - não sabia que elas existiam ...
 rossb8310 de jan de 2017 08:40
Tenho certeza de que isso não funcionará pelos motivos mencionados acima: /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:959:14: erro: não é possível converter a partir de lvalue do tipo ' const value_type '(aka' const std :: __ 1 :: basic_string <char> ') para rvalue o tipo de referência' reference '(também conhecido como' std :: __ 1 :: basic_string <char> && '); tipos não são compatíveis return static_cast <reference> (* __ i); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~

eu sugeriria ostd::move_iterator adaptador, mas isso não funciona porque a chave de um mapa é const.

Em outras palavras, você não pode mover elementos um a um de um mapa, pois isso pode alterar as chaves, o que um mapa não permite.

E não há como simplesmente mover em massa de um mapa para outro. As listas suportam emenda, mas receio que as árvores não.

 Sebastian Redl12 de fev de 2014 12:06
Se você deseja mover a partir do elemento de um mapa, essa é uma operação de movimentação desse par. Mas você não pode passar de algo que é const.
 Gabriel12 de fev de 2014 11:50
Eu não entendo direito, os tipos subjacentes sãostd::pair<const key_type, value_type>, por que as chaves podem mudar?mapped_type detemp e mova param ?
QuestionSolution

DICA: Leia a atualização primeiro!

O padrão atual do C ++ 11 e o rascunho do C ++ 14 não fornecem uma função de membro para habilitar esse recurso. Como Lavr sugeriu, você ainda pode escrever

m.insert(make_move_iterator(begin(temp)),
         make_move_iterator(end  (temp)));

que moverá ovalores do contêiner de origem para o contêiner de destino. No entanto, nem os nós do contêiner nem as chaves serão movidas. Isso requer alocações de memória (pelo menos para a criação dos novos nós no mapa de destino). O número de elementos no contêiner de origem permanecerá o mesmo. A razão por trás da cópia é simples: o tipo de valor destd::map éstd::pair<const Key,T>. E passando deconst Key é essencialmente copiar a chave (a menos que alguém sobrecarregue oKey construtor que leva umconst Key &&, pelo qual não consigo pensar em uma razão adequada).

Se você precisar mover dados de um contêiner para outro, considere usarstd::list ao invés destd::map. Tem umfunção membrosplice que move os elementos de uma lista para outra em tempo constante.

ATUALIZAR:

Desde C ++ 17, existe a funçãostd::map::merge() que basicamente coloca todos os elementos de umstd::map em outrostd::map sem mover ou copiar os elementos reais, mas substituindo apenas ponteiros internos. É muito parecido comstd::list::splice() que existe desde C ++ 98.

Então você pode escrever

m.merge( temp );

para atingir seu objetivo. Isso é mais eficiente do que copiar ou mover todos os elementos de um contêiner para outro.

Mas cuidado! Chaves conflitantes não serão resolvidas: para chaves coincidentes, nada será feito.

 Ralph Tandetzky12 de fev de 2014 18:18
@lavr Sim, de fato.
 iavr12 de fev de 2014 16:21
Enquantoconst Key serão copiados ao mover o par e enquantotemp manterá o mesmo número de elementos,T ainda será movido ... então seT é uma estrutura grande com semântica de movimento comostd::vector, isso ainda faz sentido, certo?

yourAnswerToTheQuestion