Insert on lookup is convenient but encourages either double-lookup patterns (contains + get) or unintentional inserts. I very much like Python's setdefault -- except for its 10-chars name.
Well, STL encourages an iterator centric approach, so:
if(auto i = x.find(y); i!=x.end()){
// use i->{first,second}
}
Also ideally you should be able to do this:
for(auto [key, value]: x.equal_range(y)) {
}
But infuriatingly, x.equal_range returns a pair instead of some range view so you need some additional infrastructure (either convert the result of equal range into a range or add some begin/end overloads for pair).
My C++ is a bit rusty (no puns intended), I didn't know your first syntax was possible now (another comment states it comes from C++17), that's much nicer than the alternative that pollutes the scope indeed. Having to repeat both x and i is unfortunate, but that's par for the course with C++ iterators.
The equal_range solution looks nice from a genericity perspective (look ma I do multimaps!) but is really unintuitive with regular maps imo. Unless I'm mistaken it also does not allow an else branch for when the value is not there, which is often needed.
For-else could be useful, but I don't think Python's semantics would actually help here? Python's for-else runs when the for loop did not break (even if nonempty), but what would be needed here would be to run when the for loop was empty, which is a different condition.
cpp2 is both interesting and ambitious, I really hope it gets somewhere.
Yeah for-else as implemented in Python is... not actually that useful. It's the right tool to inline std::find_if and that's basically it. I think the behavior you had in mind would actually be more intuitive and more useful.