Jump to content
  • Advertisement
Sign in to follow this  
freeworld

is there a container for this or write my own?

This topic is 2525 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

brainfart... I've got a vector of structs, that contain a string value. I'd like to be able to look into the vector using the string value as the index like so.

vector<struct> myStructs;
int health = myStructs["health"].value;

is there a container that can already do this for me, or should I just wrap the vector in a class that overrides the [] operator? The other things is, it kinda needs some sort of error checking, there's definitely times were the string won't exist, so returning a blank struct (ie 0) would be prefered.

Share this post


Link to post
Share on other sites
Advertisement

Yes you are looking for http://www.cplusplus...erence/stl/map/


ooh, quick question, what happens if I try to push an element onto a map with a key that matchs an already existing element? Do I need to handle these errors on my own or will it ignore the new value?

and what happens if I try to access an element but the key doesn't exist... ie there is no value in the map that has the key "health" but I try to access it anyways?

Share this post


Link to post
Share on other sites
Both of those questions are thoroughly described in the reference that was linked. Basically, you go to the function you're using to do that and check what the result are and what they mean.

Share this post


Link to post
Share on other sites
The value is overriden. If you want to have more than one element with the same key (the key in this case would be "health") then you're looking into multi_map

Note however, games are performance critical and using strings to address data is very inefficient. And map causes lots of cache misses too. I only use strings (& std::map) to store game's data (i.e. to store it in HDD) and then be processed at loading time. If this is used every frame by every entity in your scene, it may affect your performance seriously.

Share this post


Link to post
Share on other sites

The value is overriden. If you want to have more than one element with the same key (the key in this case would be "health") then you're looking into multi_map


Are you sure? The reference says it doesn't get modified.

Share this post


Link to post
Share on other sites

Both of those questions are thoroughly described in the reference that was linked. Basically, you go to the function you're using to do that and check what the result are and what they mean.


ok it states that if I try to access a key that doesn't exist it creates a new element with that key.... but does map not use push to add elements? do I have to use insert or the [] operator?


The value is overriden. If you want to have more than one element with the same key (the key in this case would be "health") then you're looking into multi_map

Note however, games are performance critical and using strings to address data is very inefficient. And map causes lots of cache misses too. I only use strings (& std::map) to store game's data (i.e. to store it in HDD) and then be processed at loading time. If this is used every frame by every entity in your scene, it may affect your performance seriously.


nothing huge going on here, I wouldn't think I'd have an issue, if each map i no more than 10-15 elements in size and typically only ~5. and access every map anywhere from 150-3K times every second... I wouldn't think I'd notice it at all. The need for the dynamic storage of data based on a name is more important then an extra fps.

Also I don't need to store multiple values with the same name, in fact that should never happen, but there is the chance that I might try to add another value with the same name, I want the enw value to be completely ignored/rejected, not override the old value.

Share this post


Link to post
Share on other sites

ok it states that if I try to access a key that doesn't exist it creates a new element with that key.... but does map not use push to add elements? do I have to use insert or the [] operator?

If you use /"]operator [] to insert elements, then the new item will overwrite the existing item.

If you instead use the insert() function, it will not replace existing elements, and will return a boolean to indicate success.

You can also use the find() function, to check for an existing item, and then pass the resulting iterator into insert(), which will cut down the cost of performing find+insert.

Share this post


Link to post
Share on other sites

ok it states that if I try to access a key that doesn't exist it creates a new element with that key.... but does map not use push to add elements? do I have to use insert or the [] operator?

These have been said by swiftcoder, but just to clarify:

  1. Map doesn't have push_back
  2. myMap["myKey"] = 20 -> creates the entry "myKey" and set it to 20. If "myKey" already existed, it overwrites it's contents.
  3. int myVal = myMap["myKey"]; ->Watch out when you do that, because if the entry "myKey" didn't exist, you may be reading uninitialized memory (unless the mapped value has a default constructor that sets it's contents to valid values).
  4. std::map<int>::iterator it = myMap.find( "myKey" ) -> Reads the value at "myKey". If it didn't exist, returns myMap.end() instead (doesn't create a new entry).



nothing huge going on here, I wouldn't think I'd have an issue, if each map i no more than 10-15 elements in size and typically only ~5. and access every map anywhere from 150-3K times every second... I wouldn't think I'd notice it at all. The need for the dynamic storage of data based on a name is more important then an extra fps.

150 is not the same as 3k; and is not the same per frame than per second. Be sure you understand timing. If you access the map 3k in your loop iteration, that's 3k * 60 = 180k per second; which can badly hurt performance since the keys are strings. 3k per second though, is fine.

Also take in mind:

  1. Map is designed for amortized-time accessing of a large number of elements. That means map is designed to hold like 1.000's or 10.000's of values in the same map. If they're gonna have like 15, may be you should roll your own using a struct and a std::vector with linear search (see std::find). However, if you really access like 3k per second, then may be you just stick to map; it's quicker to code and you won't notice performance problems
  2. The thing about using strings is that, when used carelesssly can greatly increase the memory size as well as the memory fragmentation, which is the most damaging element to a video game. That's the reason of my warning. Cache misses can also cause surprising slowdowns even of cutting edge CPUs.
  3. It's rather strange to see someone doing myMap["health"] to store or read a simple common value like health; which seemed like wrong usage to me. May be you were just using as an example only.


Also I don't need to store multiple values with the same name, in fact that should never happen, but there is the chance that I might try to add another value with the same name, I want the enw value to be completely ignored/rejected, not override the old value.

If you stick to map; don't use myMap["key"] = 10; but rather myMap.insert() like swiftcoder suggested.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!