std::map iteration

Started by
4 comments, last by rollo 16 years, 11 months ago
Okay, I'm using an std::map to store image pointers that are associated with id numbers. So, if you reference "1" it will reference the image that is associated with "1". It is part of a class and I want to have a method that will free all the images from memory. The way that it is now, someone could have image "1" and image "5". If it were an std::vector, I could just use a for loop to cycle through until the iterator was larger than the size of the vector, but I'm not sure that this is the case with a map, because you reference the item by it's association key, not it's number in the list. So... I don't think I worded this post too well, but basically, how can I cycle through an std::map without using the "key" value, but instead, just iterate through all the items?
Advertisement
By using iterators, a concept that is common to all the SC++L's containers, and is very important for the generic algorithms and such. Iterators act a lot like pointers, in that you can dereference them (* or ->) to get what they refer (point) to. (In the case of std::map and std::multi_map, the container actually contains a set of std::pair<key, value>, rather than just values, so you dereference it and access first to get the key, or access second to get the value.)
std::map<std::string, image*> imageMap;//fill in imageMap with images...//then to erase everything:std::map<std::string, image*>::iterator imageIterator;for (imageIterator = imageMap.begin(); imageIterator != imageMap.end(); ++imageIterator){  delete imageIterator->second;}imageMap.clear();

However, I would recommend using some form of smart pointers (perhaps boost::shared_ptr) instead of using raw pointers. Then all you need to do is remove elements from the map, and never explicitly delete them. Much nicer that way.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Iteration is done with iterators. Hence the name. [wink]

All containers in the C++ standard library supply iterators.

So basically, you'd do something like this:
for (<type of your map>::iterator it = mymap.begin(); it != mymap.end(); ++it){
// Do stuff here
}

That works for maps, strings, vectors, sets and whatever other container you can think of.
How to iterate over a std::container?

Why, using an iterator of course [smile].

typedef std::map<int,SomeType*> SomeTypeMap;SomeTypeMap someTypeMap;addStuffToMap(someTypeMap);for( SomeTypeMap::iterator it = someTypeMap.begin() ; it != someTypeMap.end() ; ++it ){     delete it->second;}someTypeMap.clear();


Or we could use boost::shared_ptr:
typedef std::map<int,boost::shared_ptr<SomeType> > SomeTypeMap;SomeTypeMap someTypeMap;addStuffToMap(someTypeMap);someTypeMap.clear();
with an iterator of course!
I believe this is the syntax:

std::map<int, std::string> lookUpTable;// fill the look up tablefor(std::map<int, std::string>::iterator i = lookUpTable.begin(); i != lookUpTable.end(); ++i){  // do stuff}


edit: Jinx (for rip-off)

You guys are fast

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

you can do it with normal iterators, its just that the values are going to be a std::pair, in your case I guess std::pair<std::string, Image*>, I prefer to use stl algorithms for stuff like this. here is an example using for_each:

// functor that deletes the second part of an image pair.struct DeleteImage {  void operator() (MyClass::ImageMap::value_type p) {    delete p.second;  }};class MyClass {public:  // or whatever it is you have, typedefs are nice so you dont  // have to repeat yourself  typedef std::map<std::string, Image*> ImageMap;  ~MyClass() {    // clean up all images    std::for_each(images.begin(), images.end(), DeleteImage());  }private:  ImageMap images;};


Hopefully thats ok, I just typed it in, no testing ;)
DeleteImage can be made more general too with templates so if you need to do this often it can be reused.

[Edited by - rollo on May 6, 2007 4:28:31 PM]

This topic is closed to new replies.

Advertisement