Reputation: 476
So I am trying to set an unordered_map as value for another unordered_map. Now I have the problem that I am not able to put values into the second unordered_map. My code looks like this.
std::string postCode;
std::string[] postCodeSource = new std::string{1111,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]);
}
classes:
class Foo{
public:
Foo();
Foo(std::string postCode);
std::string firstName,Customername,postCode;
}
Foo(std::string postCode);
is a simple copy constructor.
Now when I reach data[lastPlz.getString()]->at(int(k1.customer)) = new Foo(&k1);
I get an out of range exception from unordered_map which makes sense since there is no object at k1.customer yet!
Before I changed the code I created and filled a pointer looking like that.
std::unordered_map<int,Foo*> kdnrMap
kdnrMap[k1.customer] = new Foo(&k1);
and later on, I added kdnrMap to data. That won't work anymore the way I intended since this method would need a completely filled kdnrMap before I can add it to data which I can't do anymore.
So I am looking for help to get kdnrMap filled I've tried pretty much anything I could think of for now.
Upvotes: 2
Views: 890
Reputation: 3106
You don't really need to store the inner map as a pointer. Just let the outer map own the inner one like this:
std::unordered_map<std::string,
std::unordered_map<int, std::unique_ptr<Foo>>> data;
data[postCode][int(k1.Kundennr)] = new Foo(&k1);
I advise against using raw pointers here, since there is a high risk of leaking memory if you replace a value in the inner map. Using std::unique_ptr
makes it so much simpler to deal with pointers.
Your exception probably happens because unordered_map::at
requires the value to contain the key you are asking for, in order to retrieve the reference to the value it is mapping. If you use operator[]
instead like in my example, the map will create an entry if the key is not found.
If you still insist on having the outer map's values to be pointers to the inner map, then you can add elements like this:
std::unordered_map<int, Foo*> &inner = *data[postCode];
inner[int(k1.Kundennr)] = new Foo(&k1);
or
data[postCode]->operator[](int(k1.Kundennr)) = new Foo(&k1);
Upvotes: 2