En C ++, ¿está bien robar recursos de un mapa que ya no necesito? Más precisamente, suponga que tengo un std::mapcon std::stringclaves y quiero construir un vector a partir de él robando los recursos de las mapteclas s usando std::move. Tenga en cuenta que dicho acceso de escritura a las claves corrompe la estructura de datos interna (orden de las claves) del mappero no la usaré después.
Pregunta : ¿Puedo hacer esto sin ningún problema o esto conducirá a errores inesperados, por ejemplo, en el destructor del mapporque lo accedí de una manera que std::mapno estaba destinada?
Aquí hay un programa de ejemplo:
#include<map>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
std::vector<std::pair<std::string,double>> v;
{ // new scope to make clear that m is not needed
// after the resources were stolen
std::map<std::string,double> m;
m["aLongString"]=1.0;
m["anotherLongString"]=2.0;
//
// now steal resources
for (auto &p : m) {
// according to my IDE, p has type
// std::pair<const class std::__cxx11::basic_string<char>, double>&
cout<<"key before stealing: "<<p.first<<endl;
v.emplace_back(make_pair(std::move(const_cast<string&>(p.first)),p.second));
cout<<"key after stealing: "<<p.first<<endl;
}
}
// now use v
return 0;
}
Produce la salida:
key before stealing: aLongString
key after stealing:
key before stealing: anotherLongString
key after stealing:
EDITAR: Me gustaría hacer esto para todo el contenido de un mapa grande y guardar asignaciones dinámicas mediante este robo de recursos.
std::stringtiene una optimización de cadena corta. Lo que significa que existe una lógica no trivial en la copia y el movimiento y no solo el intercambio de punteros y, además, la mayoría de las veces el movimiento implica la copia, para que no trabaje con cadenas bastante largas. La diferencia estadística fue pequeña de todos modos y, en general, seguramente varía según el tipo de procesamiento de cadena que se realice.
constvalor siempre es UB.