Archived

This topic is now archived and is closed to further replies.

null_pointer

STL map class

Recommended Posts

I am using a STL map to map unsigned ints to images. My image class has all the appropriate copy constructors defined, but the default constructor leaves the object with no filename and thus no bitmap in memory. Why does the following pseudo-code call my image default constructor and then the copy constructor? // images - a std::map<unsigned int, image> // copy the 0-index image images[0].copy(other_image, ...); The copy function is never executed (yet), so I know it is not causing the problem. I can''t make heads or tails of the STL source code, because it is mostly inline and very hard to read. I can do this fine with the map::find function, but that''s kind of messy... Thanks!
- null_pointer Sabre Multimedia

Share this post


Link to post
Share on other sites
The reason is that [] on map works like find _AND_ insert, to do this the code goes something like:


map::operator[] (key)
{
if(key not in map)
{
insert key and a default construct value
}

return refrence to value for key
}

So it first calls the default constructor, then returns a reference that you can assign to. This also makes maps slower than using find or insert directly. You should use insert instead, e.g.

images.insert( make_pair(0, whatever));

Edited by - Wilka on July 21, 2000 5:11:10 PM

Share this post


Link to post
Share on other sites
Wilka:

The value of ''0'' already has an image associated with it in the list of images. So I am wondering why in the world it is trying to insert a new image if one is already present? I simply want to look up the existing image.


image myimage("default.bmp");
images.insert(image_container_type::value(0, myimage));
images[0].copy(...);



It works fine until I hit the operator[], which should simply return a reference to myimage, right? Instead, the default constructor is called, and then the copy constructor on the object constructed with the default constructor. According to the docs, it should just return find() if the object is already in the map, right?




- null_pointer
Sabre Multimedia

Share this post


Link to post
Share on other sites
Hmmm, that does seem a bit odd.

I checked operator[] for std::map, and it''s defined like this:

quote:

_Tref operator[](const key_type& _Kv)
{iterator _P = insert(value_type(_Kv, _Ty())).first;
return ((*_P).second); }



value_type is pair(const _K, _Ty) (I''m using brackets instead of greater & less so you can see them in the post).

The return value of insert is a pair. ''first'' is an iterator to the element inserted (or the existing one if it''s already there) and ''second'' is a bool. true means the element was inserted, false means it wasn''t.

So when you use [] on a map it calls insert with the key passed in and a default constructed value (i.e. _Ty()). Then it returns a reference to ''second'' (the value type) of the iterator returned from insert.

I didn''t realise this happened with std::map (I thought it called find, then insert if needed), but most of the time I use insert and find so it''s never affected me.

So it looks like you''ll have to use find instead of [] if you don''t want a default constructor to be used. e.g.


image myimage("default.bmp");
images.insert(image_container_type::value(0, myimage));
images.find(0)->second.copy(...);


It''s a bit more code and isn''t as easy to read as using [], but at least you now it''s faster and it doesn''t need to create a temp object.

Share this post


Link to post
Share on other sites
Wilka:

Thanks, but I know how to use find.

Anyway, what I don't understand is that, when I use the [] operator, passing it a key for an element that _is_ in the map, two constructors are called. Besides the temp object, a copy of the temp object is constructed. That copy of the invalid object is what crashes my drawing routine.

Why the second copy?

I'll just go back to using find...




- null_pointer
Sabre Multimedia


Edited by - null_pointer on July 22, 2000 12:21:44 PM

Share this post


Link to post
Share on other sites