4 ms·
C++ operator [] is poorly designed: index, and index+assignment should be two different operators, and indexing alone should never insert new entries into the m
by nialv7 10mo ago
C++ operator [] is poorly designed: index, and index+assignment should be two different operators, and indexing alone should never insert new entries into the map.
Languages like D [0] or Rust [1] get this right.
[0]: https://dlang.org/spec/operatoroverloading.html#index_assignment_operator https://dlang.org/spec/operatoroverloading.html#index_assign...
[1]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html https://doc.rust-lang.org/std/ops/trait.IndexMut.html
- gpderetta 10mo agoYou could (and I would) make the opposite statement: upsert should be the default operator and if you want lookup only or insert only you call different operators. I find it annoying that I often have to reach to defaultdict in Python to get this behavior.
- hmry 10mo agoI certainly use defaultdict often in Python too, but not more often than the regular dict. Maybe 90% dict and 10% defaultdict. So from my POV lookup only should definitely be the default.
- tialaramex 10mo agoC++ could offer the entry API here, so you can get back a type representing the result of finding where this key would go, and then either it has a key+value pair you can mutate if you want, or it has a blank state allowing you to write a new key+value pair if that's what you want, without redoing the potentially expensive find operation to figure out where to put the new/updated pair
- Tempest1981 10mo agoiirc, there are 5 ways to put something into a std::map operator[], insert(), emplace(), try_emplace(), insert_or_assign() And 2 of them don't overwrite an existing value. Lots of people are surprised that insert() can fail. And even more surprised that a RHS [] inserts a default value. I'm not a fan of APIs that surprise.
- ruszki 10mo ago> I'm not a fan of APIs that surprise. It really depends on what you got used to. C++ was the first language, which, I would say, learned. I’m still surprised to day that traversing a set is not in order by default. In this specific case, emplace should be your default option, and you should really know why that’s the case, and why you have this many options.