En C ++, ¿está bien robar recursos de un mapa que ya no necesito? Más precisamente, suponga que tengo un std::map
con std::string
claves y quiero construir un vector a partir de él robando los recursos de las map
teclas 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 map
pero 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 map
porque lo accedí de una manera que std::map
no 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::string
tiene 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.
const
valor siempre es UB.