How do I insert a element into a std::unordered_map<int, vector<Object*>>
Asked Answered
B

3

5

I'm trying to create a hash of arrays of pointers to my object.

The hash key is an int for the type of the object, and the array is a list of the objects to render.

What I'm trying to do is :

unordered_map<int, vector<Object*> > drawQueue;
drawQueue.clear(); // new empty draw queue

for ( ... ) {
   drawQueue.at(type).push_back(my_obj);
}
 

So I'm not familiar enough with the nuances of the STL stuff, since I get an exception saying out_of_bounds, which is what happens when the key doesn't exist.

So I figured I need to create the key first, and then add to the vector :

if (drawQueue.count(type)) {
    // key already exists
    drawQueue.at(type).push_back(my_obj);
} else {
    //key doesn't exist
    drawQueue.insert(type, vector<Object*>); // problem here
    drawQueue.at(type).push_back(my_obj);
}

But now I'm really lost, as I don't know how to create/initialise/whatever an empty vector to the insert of the unordered_map...

Or am I doing this the entirely wrong way?

Basilicata answered 18/6, 2012 at 10:51 Comment(1)
Did you have a look at operator[] ? or the actual documentation of insert() ?Pep
H
10

You are not using insert in the proper way. This should work:

drawQueue.insert(std::make_pair(type, std::vector<Object*>()));

If using C++11, the previous statement can be simplified to:

drawQueue.emplace(type, std::vector<Object*>());

By using this approach the element is constructed in-place (i.e., no copy or move operations are performed).

I also include links to the documentation for insert and emplace.

Herewith answered 18/6, 2012 at 10:58 Comment(3)
In C++11 you can say drawQueue.emplace(type);.Clothilde
@KerrekSB It does not work for me with GCC 4.6 (using -std=c++0x). Which compiler are you using?Herewith
@KerrekSB I tried with GCC 4.7 and it worked :) I will update my answer to include that possibility.Herewith
L
6

I think this is an easy approach. My example will create an unordered_map string as key and integer vector as values.

unordered_map<string,vector<int>> keys;
keys["a"] = vector<int>(); // Initialize key with null vector
keys["a"].push_back(1); // push values into vector.
keys["a"].push_back(5);    
for(int i : keys["a"] ){
    cout << i << "\t";
}
Lovable answered 21/11, 2017 at 1:58 Comment(1)
Is there some way to check if the vector is initialized or not, since it's not a pointer? You wouldn't want to do that if came back later and wanted to push_back onto key "a". Would checking .size() work, or would that throw an error if it's not initialized?Ultra
F
0

I think you could simplify it by

drawQueue[type].push_back(my_obj);

The operator [] would do the insert for you if the key is not found.

Fiorenze answered 22/4, 2022 at 19:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.