6 ms·
I don't think it's _that_ unnatural to just return a reference to a dummy value (i.e. have a member T map<T>::dummy and always return that if the key does not e
by madars 4y ago
I don't think it's _that_ unnatural to just return a reference to a dummy value (i.e. have a member T map<T>::dummy and always return that if the key does not exist). Users writing to it/reading from it are on their own; you could even reinitialize it on every such operator[] call.
- cmovq 4y agooperator[] is not only used for lookups though, it’s also used for insertions: m["nonexistent"] = 1; This would not work if you return a dummy value.
- madars 4y agoThat's true; thanks! It's 3am and time for bed :-)
- 8n4vidtmkvmk 4y agoThis is why I gave up on [] and just use .at now.
- vitus 4y agoWhich is perfectly reasonable if you're willing to deal with the performance consequences of exceptions (or crashes). .find() is the safe way to do map lookup without side effects.
- colonwqbang 4y agoIt is a quirk of C++ that element lookup and assignment are forcibly unified like this. Ruby for instance has an operator[]= which could solve the problem.
- gpderetta 4y agoYou could do it in C++ via proxy objects, but are kind of tricky to get right.
- raverbashing 4y ago"quirk" looks more like "major overlooked detail" to me I mean, left side expressions and right side expressions are different
- tialaramex 4y agoIndeed, Rust's HashMap implements Index<&T> but not IndexMut<&T> meaning you can write this: let salary = salaries["Jim Bob"]; // Note this panics if "Jim Bob" isn't a key in salaries, by analogy to arrays which panic if you do an out-of-bounds array access However you can't write this, it won't compile: salaries["Jim Bob"] += 10_000; // No raise for Jim Bob, this does not compile because that's not a mutable reference.
- deredede 4y agoTo be fair, you could achieve the same in C++ by only implementing `operator[]() const`.
- tialaramex 4y agoHuh. Does that do the same thing? I can't figure it out in my head whether this causes all the correct things to fail and everything else to work.
- deredede 4y agoIf you only implement operator[]() it should do the same thing as only implementing Index in Rust, thanks to implicit cast conversion. Whether it causes "the correct things to fail and everything else to work" is up to interpretation, as this will give you const references to the array values, which is much less idiomatic in C++ than in rust.
- tialaramex 4y agoYeah, I think this probably does what I think ought to happen here, but in the process it probably makes a bunch of reasonable looking C++ not work, and thus would make programmers unhappy which is not a good goal :/
- asveikau 4y agoThey're not forcibly unified if you don't use operator overloading. There is a find() and an insert(). I tend to use find() when doing a read only lookup, and operator overloading for writing.
- masklinn 4y agoThere are two issues with that: - what is the dummy value? does the value type even have one? - I don't think index-assignment (or attribute-assignment) is overloadable in C++, so you need `a[b]` to return something which can be assigned to, and proxy values tend to be really wonky (see: `vector<bool>`), so assigning to the result of the indexing would replace the dummy value