auto v = vector<int> { 1, 2, 3 };
auto &e = v[0]; // plan to use element later
// ...
v.push_back(v.size());
// ...
cout << e << "\n"; // boom
As a real example of this: suppose you're managing a vector of connected users. v is large enough to hold 64 user structs. e is a reference to the last user who produced an event. If a 65th user connects then the vector will need to be reallocated, thereby invalidating e.Rust saves you here. The compiler will let you have a reference to the element if the vector is marked as immutable. If the vector is marked as mutable the compiler will yell at you and you'll need to store an index instead.
So, mark it as const here and see the same effect?
c++ will let you push_back while holding a reference to an element of that vector. rust will not.
So, if you have a const reference, you can't make this mistake in it's entirety, but you can certainly make the mistake of keeping a reference to something you got through a const pointer.
Also, marking as const is something you have to opt-in to, and there is still disagreement on the value of const.
That is the point of C++, things other languages do at a language level you can easily design as a library without paying a cost if you do not use it.
You do not pay a performance cost for borrowing semantics in rust.
Which is precisely what Rust does.
#include "msemstdvector.h"
// ...
auto v = mse::mstd::vector<int> { 1, 2, 3 };
auto e = v.begin() + 0; // 'e' is a safe iterator here
// ...
v.push_back(v.size());
// ...
cout << *e << "\n"; // no problem
Not much different from your original code.Rust's policy of static enforcement of "exclusive mutable references" still might be preferable in many cases, but there is a practical option of using C++ in a safe(r) way.