将 unordered_map 设置为 unordered_map 的值
Posted
技术标签:
【中文标题】将 unordered_map 设置为 unordered_map 的值【英文标题】:Setting unordered_map as value for unordered_map 【发布时间】:2020-02-19 15:20:02 【问题描述】:所以我试图将 unordered_map 设置为另一个 unordered_map 的值。 现在我遇到的问题是我无法将值放入第二个 unordered_map。 我的代码如下所示。
std::string postCode;
std::string[] postCodeSource = new std::string1111,2222,3333,4444;
std::unordered_map<std::string,unordered_map<int,Foo*>*> data;
int k1=1234;//can be any number
for(int i = 0; i < 4; i++)
postCode = postCodeSource[i]
if(data[postCode]==NULL)
data[postCode]=new std::unordered_map<int,Foo*>();
data[postCode]->at(int(k1)) = new Foo(postCodeSource[i]);
类:
class Foo
public:
Foo();
Foo(std::string postCode);
std::string firstName,Customername,postCode;
Foo(std::string postCode);
是一个简单的复制构造函数。
现在,当我到达 data[lastPlz.getString()]->at(int(k1.customer)) = new Foo(&k1);
时,我从 unordered_map 得到一个超出范围的异常,这是有道理的,因为 k1.customer 还没有对象!
在我更改代码之前,我创建并填充了一个看起来像这样的指针。
std::unordered_map<int,Foo*> kdnrMap
kdnrMap[k1.customer] = new Foo(&k1);
后来,我将 kdnrMap 添加到 data。 这将不再按我的意图工作,因为此方法需要一个完全填充的 kdnrMap 才能将其添加到 data 中,而我不能再这样做了。 p>
所以我正在寻求帮助以填充 kdnrMap 我已经尝试了几乎所有我现在能想到的东西。
【问题讨论】:
这里缺少很多代码。 minimal reproducible example 可能会让这个问题很容易解决。Foo
, Foo2
;一个实际编译的最小示例。我们可能会从您的文字描述中挑出您的问题,但这不必要地复杂和模棱两可。只需编写一些简单的代码来演示您的问题。
请注意operator[]
相当昂贵,除非确实需要多次使用,否则最好只使用一次。您作为您的地图似乎拥有数据的所有权,您最好使用智能指针。
顺便说一句,为什么需要将内部地图存储为指针?只是为了让你的代码更复杂、更容易出错?
那么你不仅让它更复杂而且更慢,因为会涉及另一个不必要的间接。猜猜std::unordered_map
将其数据存储在哪里?
【参考方案1】:
您实际上并不需要将内部映射存储为指针。让外部地图拥有内部地图,如下所示:
std::unordered_map<std::string,
std::unordered_map<int, std::unique_ptr<Foo>>> data;
data[postCode][int(k1.Kundennr)] = new Foo(&k1);
我建议不要在这里使用原始指针,因为如果您替换内部映射中的值,内存泄漏的风险很高。使用std::unique_ptr
使得处理指针变得非常简单。
您的异常可能发生,因为unordered_map::at
要求该值包含您要求的键,以便检索对它正在映射的值的引用。如果您像我的示例中那样使用operator[]
,则如果找不到密钥,则映射将创建一个条目。
如果您仍然坚持将外部映射的值作为指向内部映射的指针,那么您可以添加如下元素:
std::unordered_map<int, Foo*> &inner = *data[postCode];
inner[int(k1.Kundennr)] = new Foo(&k1);
或
data[postCode]->operator[](int(k1.Kundennr)) = new Foo(&k1);
【讨论】:
谢谢! ->operator[] 完全符合我的要求。我可能对此不以为然,但我使用内部地图作为指针,因为我认为它会更快。我不确定我是否应该使用智能指针,我正在开发一个超过 20 年的程序,我们有很多原始指针,我被教导不要混合这两个 你的想法是错误的,如果你幸运的话它不会慢 如果您不能使用智能指针,请注意data[postCode][0] = new Foo()
如果您不检查同一键是否存在先前的条目,则可能会泄漏内存。总而言之,unordered_map
从 C++11 开始就存在了,所以如果你在旧代码中包含一个现代特性,你不妨好好做。
所有来自数据库的数据邮政编码(显然)不是唯一的。但是第二个迭代器是一个唯一的客户 ID,所以如果这只是被覆盖的可能性很小甚至不存在。仍然感谢您的建议!以上是关于将 unordered_map 设置为 unordered_map 的值的主要内容,如果未能解决你的问题,请参考以下文章
boost::unordered_map 中以结构为键的 boost 变体