c++ - remix - smart contracts ethereum
¿Puedo mover-asignar el contenido de un std:: map a otro std:: map? (3)
No creo que esto sea posible. Con otros contenedores, sugeriría el adaptador std::move_iterator
, pero eso no funciona porque la clave de un mapa es const.
En otras palabras, no puede mover elementos uno a uno de un mapa porque eso podría cambiar las claves, lo que un mapa no permite.
Y no hay manera de simplemente mover en masa de un mapa a otro. Las listas admiten el empalme, pero me temo que los árboles no.
¿Es posible insertar el contenido de un std :: map temp
en otro std :: map m
usando la semántica de movimientos, de modo que los valores del temporal no se copien y se reutilicen?
Digamos que uno tiene:
std::map<int, Data> temp;
std::map<int, Data> m;
Una forma de copiar valores de temp
en m
es:
m.insert(temp.begin(),temp.end());
¿Cómo puedo mover los elementos temp
a m
, en lugar de copiar?
No lo he intentado, pero creo que std::move_iterator debería ayudar aquí:
using it = std::map<int, Data>::iterator;
using mv = std::move_iterator <it>;
m.insert(mv(temp.begin()),mv(temp.end()));
SUGERENCIA: ¡ Lee la actualización primero!
El estándar actual de C ++ 11 y el borrador de C ++ 14 no proporcionan una función miembro para habilitar esta función. Como lavr sugirió que todavía puedes escribir
m.insert(make_move_iterator(begin(temp)),
make_move_iterator(end (temp)));
que moverá los valores del contenedor de origen al contenedor de destino. Sin embargo, ni los nodos contenedores ni las claves se moverán. Esto requiere asignaciones de memoria (al menos para la creación de los nuevos nodos en el mapa de destino). El número de elementos en el contenedor de origen seguirá siendo el mismo. La razón detrás de la copia es simple: el tipo de valor de std::map
es std::pair<const Key,T>
. Y pasar de una const Key
es esencialmente copiar la clave (a menos que alguien sobrecargue el constructor de Key
que toma una const Key &&
, por lo que no puedo pensar en una razón adecuada).
Si necesita mover datos de un contenedor a otro, puede considerar usar std::list
lugar de std::map
. Tiene un splice
función miembro que mueve los elementos de una lista a otra en tiempo constante.
ACTUALIZAR:
Desde C ++ 17, existe la función std::map::merge()
que básicamente coloca todos los elementos de un std::map
en otro std::map
sin mover ni copiar los elementos reales, pero solo al volver a colocar los punteros internos . Es muy similar a std::list::splice()
que existe desde C ++ 98.
Así que puedes escribir
m.merge( temp );
para lograr tu objetivo Esto es más eficiente que copiar o mover todos los elementos de un contenedor a otro.
¡Pero cuidado! Las claves en conflicto no se resolverán: para las claves coincidentes no se hará nada.