Damn you're good! Thank you, it now works exacly as I wanted. I should have checked the contents of the map before asking. Martin
Tony Wetmore wrote:
The "problem" here appears to be that the first element is actually inserted with a key value of 1, rather than 0. This happens because the key parameter passed to std::map<>::operator[] is passed by reference, rather than by value (const key_type& __k).
So, when you insert the first element into your map, the object is constructed, then nextid is incremented to 1. After this is done, the element is inserted, with a key value of 1, rather than 0.
On the subsequent operator[] calls, nextid is set to 1, so it looks for an entry with a key of 1, and finds the first object that was created.
Adding the additional call to the toto constructor increments the nextid by one, which causes the code to "work", although the objects are still inserted with the "wrong" (I believe) key value. That is, of course, assuming that in this code the key value should match the "id" of the toto object.
If you print out the contents of the map after each call to toto::create(), you'll see the effect that I'm talking about.
So this does not appear to be a bug in the C++ library, but rather an unfortunate side effect of the fact that the key type is passed by reference, rather than by value. And since, in your case, that key object changes value "midway" through the insertion, you get bad behavior.
To fix the problem, you could store the current value of nextid in a temporary within toto::create() and use that in the map indexing operation instead:
static const toto* create() { unsigned int n = nextid; return &totos[n]; }
That causes the map to be created with key values that match the "id" of each object in the map, verified by printing out the map after each call to toto::create().
--- Tony Wetmore Raytheon Solipsys mailto:tony.wetmore@xxxxxxxxxxxx http://www.solipsys.com
-----Original Message----- From: gcc-help-owner@xxxxxxxxxxx [mailto:gcc-help-owner@xxxxxxxxxxx] On Behalf Of Martin Voelkle Sent: Tuesday, August 26, 2003 10:03 AM To: gcc-help@xxxxxxxxxxx Subject: c++ std::map problem
Hello,
please cc me.
I'm having trouble making this snip of code work. I just want to keep a map of created objects (for (un)marshalling), but when I run the attached code, I see that the constructor is only called once, giving an
output of 0111.
Now if I make this change: - static const toto* create() { return &totos[nextid]; } + static const toto* create() { toto(); return &totos[nextid]; } I get 0246, which is what is expected, but not the initial objective.
Am I doing something wrong? Is there a bug in g++ or libstdc++? I get the problem with both 3.3.2 20030812 and 2.95.4 20011002 (Debian sid) I don't know what kind of keywords I could use to search, so I have to post.
Thank you,