OT: std::map<>::operator[] and default constructor
Please direct me to a more appropriate list if this is too off topic: It's come to my attention that our vendor's std::map<>::operator[] /always/ calls the default constructor of the key even when the key already exists in the map. This is what they say: It turned out to be a documentation bug. Our implementation is in sync with the standard. From 23.3.1.2 [lib.map.access]: T& operator[](const key_type& x); -1- Returns: (*((insert(make_pair(x, T()))).first)).second. Notice the T() in the call to make_pair() above: that's an invocation of the default ctor of the mapped type (i.e., Aoeu in the user's test case). So the program behaves as expected. If you do not like this behavior, replacing the expression map[16] in the program with map.find (16)->second will avoid the construction of the unused temporary. I modified the test case to incorporate this change. My inclination is to say the standard is a spec, not an implementation. Allowing std::map<>::operator[] not to call the default constructor requires no more and promises no less than the spec. All this is true unless, of course, there's some order of complexity issue I'm missing. But someone else had said, "an implementation has to have the same 'observable behaviour' as the abstract machine defined in the standard. Calling the default ctor definitely counts as observable behaviour, so I don't think RW have any choice but to implement it this way". What's the best place to get an official answer to the real intent of std::map<>::operator[]? Must it /always/ call the default constructor? Thanks, Noel
Noel Yap wrote:
Please direct me to a more appropriate list if this is too off topic:
Given that you post does not mention Boost anywhere, this is certainly off-topic. I suggest you do not post question when you know in advance they belong somewhere else. This specific question is on-topic for comp.lang.c++, comp.lang.c++.moderated or comp.lang.std.c++ newsgroup. Pick one ;-) - Volodya
On Feb 15, 2005, at 11:09 AM, Noel Yap wrote:
Please direct me to a more appropriate list if this is too off topic:
It's come to my attention that our vendor's std::map<>::operator[] /always/ calls the default constructor of the key even when the key already exists in the map.
This is what they say:
It turned out to be a documentation bug. Our implementation is in sync with the standard.
From 23.3.1.2 [lib.map.access]:
T& operator[](const key_type& x);
-1- Returns: (*((insert(make_pair(x, T()))).first)).second.
Notice the T() in the call to make_pair() above: that's an invocation of the default ctor of the mapped type (i.e., Aoeu in the user's test case). So the program behaves as expected. If you do not like this behavior, replacing the expression map[16] in the program with map.find (16)->second will avoid the construction of the unused temporary. I modified the test case to incorporate this change.
My inclination is to say the standard is a spec, not an implementation. Allowing std::map<>::operator[] not to call the default constructor requires no more and promises no less than the spec. All this is true unless, of course, there's some order of complexity issue I'm missing. But someone else had said, "an implementation has to have the same 'observable behaviour' as the abstract machine defined in the standard. Calling the default ctor definitely counts as observable behaviour, so I don't think RW have any choice but to implement it this way".
I believe RW is technically correct. However there is a DR on this issue with WP status: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#334 The proposed resolution no longer requires calling the default constructor (nor does it forbid it). WP status means that the committee has officially voted in favor of this resolution, but it is not yet official. It has been applied to the draft working paper for C++0X. The Metrowerks implementation has purposefully gone non-standard on this issue (until C++0X becomes official) as we believe it results in a higher quality library for our customers. I.e. we call the default constructor only if it doesn't already exist in the map.
What's the best place to get an official answer to the real intent of std::map<>::operator[]? Must it /always/ call the default constructor?
The newsgroup comp.std.c++ . -Howard
participants (3)
-
Howard Hinnant
-
Noel Yap
-
Vladimir Prus