En C ++, est-ce OK de voler des ressources d'une carte dont je n'ai plus besoin par la suite? Plus précisément, supposons que j'ai un std::map
avec des std::string
clés et que je veux en construire un vecteur en volant les ressources des map
clés s en utilisant std::move
. Notez qu'un tel accès en écriture aux clés corrompt la structure de données interne (ordre des clés) du map
mais je ne l'utiliserai pas par la suite.
Question : Puis-je le faire sans aucun problème ou cela entraînera-t-il des bogues inattendus, par exemple dans le destructeur du, map
car j'y ai accédé d'une manière qui std::map
n'était pas destinée?
Voici un exemple de programme:
#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;
}
Il produit la sortie:
key before stealing: aLongString
key after stealing:
key before stealing: anotherLongString
key after stealing:
EDIT: Je voudrais le faire pour tout le contenu d'une grande carte et enregistrer les allocations dynamiques par ce vol de ressources.
std::string
optimisation des chaînes courtes. Cela signifie qu'il existe une logique non triviale sur la copie et le déplacement et pas seulement l'échange de pointeurs et, en outre, la plupart du temps, le déplacement implique la copie - de peur de traiter avec des chaînes assez longues. La différence statistique était de toute façon faible et en général, elle varie sûrement en fonction du type de traitement de chaîne effectué.
const
valeur est toujours UB.