Most kinds of OOP can be expressed idiomatically in Rust. The big exception is implementation inheritance, which is highly discouraged in modern code anyway due to its complex and unintuitive semantics. (Specifically, its reliance on "open recursion", and the related "fragile base class" problem)
People often say that modern c++ doesn't have the problems needing a solution like rust. Ironically that means people who write modern c++ haven't had any aramp up time needed when joining our rust projects. They were already doing things the right way. At least mostly. But now they don't have to worry about that one person who seems to be trying to trick the static analysis tools on purpose.
Anything that involves object graphs (as opposed to trees) is a pain in Rust.
True, but not in a way that wouldn't be just as painful in C++.
In Rust, the de facto standard advice for such cases seems to be, "just use indices into an array instead of references".
While this is sometimes done in C++ as well for various reasons, it's certainly not the default pattern there. If you have two things that need to point to each other, you just do that.
> While this is sometimes done in C++ as well for various reasons, it's certainly not the default pattern there. If you have two things that need to point to each other, you just do that.
And then you have to handle all the subtle memory bugs that you've introduced by doing that.
I'm not arguing that there isn't a gain here, but GP's original assertion was that
> While programming in Rust, I've never thought to myself, "man, this would be so much easier to express in C++".
This is a concrete example of something that is much easier to express in C++. And, sure, you do pay the tax for that (although I will also dispute the notion that it is impossible to write C++ without memory bugs; it's just hard).
I guess this is a semantics argument, but I assume they mean to express the same thing with same (or reasonably same) security guarantees. After all, the security and "bug freeness" is part of what they are expressing. If you attempt to create something reasonably similar to Rust, you do suddenly need a lot of complex checking code and maybe tests for things that were trivial in Rust (because the compiler does the tests for you).
Is it really easy to express if the straightforward way is buggy and error-prone?
People think C++ is expressive because they think they are allowed to do a lot of things that they aren't, in fact, allowed to do in C++.