Czy w C ++ można ukraść zasoby z mapy, której już nie potrzebuję? Mówiąc dokładniej, załóżmy, że mam klucze std::map
z std::string
i chcę z niego zbudować wektor, kradnąc zasoby map
kluczy s za pomocą std::move
. Zauważ, że taki dostęp do zapisu do kluczy psuje wewnętrzną strukturę danych (porządkowanie kluczy), map
ale nie będę jej później używał.
Pytanie : Czy mogę to zrobić bez żadnych problemów, czy doprowadzi to do nieoczekiwanych błędów, na przykład w destruktorze, map
ponieważ uzyskałem do niego dostęp w sposób, który std::map
nie był przeznaczony?
Oto przykładowy program:
#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;
}
Daje to wynik:
key before stealing: aLongString
key after stealing:
key before stealing: anotherLongString
key after stealing:
EDYCJA: Chciałbym to zrobić dla całej zawartości dużej mapy i zapisać dynamiczne przydziały dzięki kradzieży zasobów.
std::string
ma krótką optymalizację. Oznacza to, że istnieje pewna nietrywialna logika przy kopiowaniu i przenoszeniu, a nie tylko wymiana wskaźnika, a ponadto większość ruchu polega na kopiowaniu - aby nie radzić sobie z dość długimi łańcuchami. Różnica statystyczna i tak była niewielka i na ogół różni się w zależności od rodzaju wykonywanego przetwarzania łańcucha.
const
wartości jest zawsze UB.