const auto &ref = v[0];
v.push_back(42);
cout << ref;
That works fine until push_back reallocates out of place, at which point you may start to notice that it’s actually UB.Rust will not permit this problematic usage. GC languages tend not to offer this pattern — you can reference a boxed vector element with different semantics than the above C++ code, and you mostly can’t reference an unboxed element. C++ lets you do things like this but has little ability to statically verify correctness.
(Doing the above maneuver with a vector is a bit silly: it saves typing, and indexing a vector is extremely fast. With a map, though, indexing is not so fast, and keeping an iterator or a reference around may be a big performance win. At least if you keep an iterator around, dynamic checkers have a better chance of noticing errors.)
Some times it can be pretty indirect: eg if the ref ends up pointing into some std container then it might need invalidated by making an otherwise unrelated change to the container.
One can debate whether the const belongs there and how many &’s to use, but, unless something has changed dramatically in the last couple years (I’ve been focused on things that aren’t C++), there is no answer that is universally safe and efficient.