4 ms·
It's missing my favorite, std::(unordered_)map::operator[] map<int,int> a; cout << a[11] << endl; cout << a.size() << endl; This works fine and has well
by lbrandy 14y ago
It's missing my favorite, std::(unordered_)map::operator[]
map<int,int> a;
cout << a[11] << endl;
cout << a.size() << endl;
This works fine and has well defined behavior: it will print '0' followed by '1' since the middle line actually inserts a {key=11, value=0}.
This is a landmine I think every journeyman c++ programmer steps on a few times.
- blablabla123 14y agoI remember being extremely cautious the last time I used std::map... Anyways, g++ -Weffc++ -Wall helps, eventhough not in this case I think ;)
- npsimons 14y agoStart with "g++ --help=warnings | grep "\-W" | awk '{print $1}' | sort | uniq", sort out the ones that don't apply to C++, add in "-pedantic" and "-fdiagnostic-show-option", then (sparingly!) disable spurious warnings via the "GCC diagnostic ignored" pragma, or just outright removal of the warning option (the first candidate that comes to mind is -Waggregate-return). Do be aware that if you are using libraries which trigger warnings, you can turn off warning checking for them with "-isystem" (but make sure to also take "-Wsystem-header" out of your list of warnings). This won't prevent every gun pointed at foot incident, but it's a good start.
- zem 14y agowow, did not know about -Weffc++. quite impressive that they added that flag. here's a blog post if anyone else wants to read about it: http://cpptruths.blogspot.com/2006/08/g-compiler-option-weffc.html http://cpptruths.blogspot.com/2006/08/g-compiler-option-weff...
- angersock 14y agoThe amazing shittiness of std::map and friends drove us to write our own, with blackjack and hookers. I really wish there was an API "Hall of Shame" with attached discussion minutes showing the exact points where a group of otherwise sane people decided to kludge these things in.
- threemonkeys 14y agoI like the style of your comment; it made me laugh aloud in an airport and brightened an otherwise shitty day. I especially like your characterization of C++ Std API designers as "otherwise sane people," which isn't exactly how I imagine them. Now, off to pour Courvoisier on those funny bumps in my groin...
- tcwc 14y agoI agree this particular example can be confusing the first time you hit it, especially coming from other languages. It's better than the alternatives though, I would be interested to hear how you handle this in your version. Leaving the behaviour undefined for non-existent keys is likely to cause far worse bugs, throwing an exception would be inconsistent with the rest of the stl. The could have left it out altogether, but would mean losing some nice properties - operator[] returning a reference makes it possible to assign into the map directly ( a[3] = 5; ). Also since the value is default initialized, you can write something like a counter easily, much like a python defaultdict: for (auto id in ids) { a[id] += 10; } You can always stick to .find and .insert if you prefer the more explicit behaviour.
- cobrausn 14y agoIn the version we ended up writing, 'operator []' is equivalent to a call to 'Get', which also returns a reference to the mapped value. In the event that key is not mapped, it asserts. If you handle the assert or have disabled runtime asserts, it returns a reference to a static value instance, so you can handle this kind of error yourself or even use the static value as a 'default' (though we never use it that way). Though not consistent with how STL works, it is consistent with how our containers work and how we use maps. YMMV. Also, since we wrote it, we're free to change the behavior if a better way manifests itself. So, if you have any suggestions, let fly.
- idupree 14y agoYou could return a proxy object that offers operator= et al, and an implicit conversion operator to T& or T const& that throws an exception if that key is not in the map. (I don't know if that would be better, since it's even more magic and it still isn't perfect.)