Em C ++, não há problema em roubar recursos de um mapa que eu não preciso mais mais? Mais precisamente, suponha que eu possua um std::map
com std::string
chaves e que eu queira construir um vetor roubando os recursos das map
chaves s usando std::move
. Observe que esse acesso de gravação às chaves corrompe a estrutura de dados interna (ordenação de chaves) da map
mas não a usarei posteriormente.
Pergunta : Posso fazer isso sem problemas ou isso levará a erros inesperados, por exemplo, no destruidor do, map
porque eu o acessei de uma maneira que std::map
não foi planejada?
Aqui está um programa de exemplo:
#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;
}
Produz a saída:
key before stealing: aLongString
key after stealing:
key before stealing: anotherLongString
key after stealing:
EDIT: Eu gostaria de fazer isso para todo o conteúdo de um mapa grande e salvar alocações dinâmicas por esse roubo de recurso.
std::string
tem otimização de cadeia curta. Isso significa que existe uma lógica não trivial em copiar e mover, e não apenas troca de ponteiros e, além disso, na maioria das vezes a mudança implica em copiar - para que você não lide com seqüências longas. De qualquer forma, a diferença estatística era pequena e, em geral, varia de acordo com o tipo de processamento de string.
const
valor é sempre UB.