在C ++中,可以从以后不再需要的映射中窃取资源了吗?更准确地说,假设我有一个std::map
with std::string
键,并且我想通过使用窃取map
s键的资源来构造一个向量std::move
。请注意,对键的这种写访问会破坏的内部数据结构(键的顺序),map
但此后我将不再使用它。
问题:我可以这样做没有任何问题吗?还是会导致意外的错误(例如,map
由于我std::map
以非预期的方式访问它)而导致了析构函数的错误?
这是一个示例程序:
#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;
}
它产生输出:
key before stealing: aLongString
key after stealing:
key before stealing: anotherLongString
key after stealing:
编辑:我想对一张大地图的整个内容执行此操作,并通过此资源窃取来保存动态分配。
std::string
具有短字符串优化。这意味着在复制和移动时存在一些不平凡的逻辑,而不仅仅是指针交换,而且在大多数情况下,移动还意味着复制-以免您处理相当长的字符串。无论如何,统计差异很小,并且总的来说,它肯定会根据执行的字符串处理类型而有所不同。
const
值始终是UB。