As someone who uses both Rust and C++ frequently with a good understanding of both languages, I can say that Rust is for the mostpart more pleasant to work in, but Rust's handicap is that it makes working in raw pointers when you really have to quite painful.
If you need full raw pointers with aliasing mutable pointers, the fact that fn drop() takes a &mut T is a problem that can only currently be worked around with fugly hacks, like nesting your data type in another pointless structure, not to mention the giant pile of ambiguous UB that you risk whenever pointers and references interact that could so easily be avoided if Rust would just implement an -fno-strict-aliasing switch, but the devs refuse on what appears to be ideological grounds. The result is that for unsafe Rust, you get about the safety level of C much of the time, because RAII and many language facilities are not safe to use. Unsafe Rust is currently so dangerous that I feel much safer reaching for C++ for some of it. Mutable reference uniqueness, I think, should be enforced by the borrow checker and NOT by pain of inescapable possible undefined behavior at the assembler level.
Now for C++.
C++ is lacking a LOT of useful safety features that Rust comes with baked in, such as Mutexes owning their data, the borrow checker, a good, fast atomic reference counting type, and things that translate to more safety indirectly, like algebraic enums, assignable and movable arrays, tuples built into the language, etc. Generics in Rust, however, are significantly more painful to write due to the lack of duck typing. Perhaps the Rust devs felt that duck typing was too "dangerous" for templates, but because they're statically evaluated, these issues almost never materialize, and so in practice duck typed templates are almost always superior to Rust's generics.
C++ is definitely more mature and pragmatic as a language, but Rust is probably better for systems programming overall, at least if they fix their goddamn unsafe UB stuff.
As for move semantics, that book isn't for "what you MUST do to keep things semi-safe!" though it contains some stuff to that effect. It's more about optimization and tricks from what I can see. Move semantics take a little while to wrap your head around, but once you know the basics of C++'s move semantics, you can pretty much figure out what's going to happen by looking at a class' definition briefly.
If you need full raw pointers with aliasing mutable pointers, the fact that fn drop() takes a &mut T is a problem that can only currently be worked around with fugly hacks, like nesting your data type in another pointless structure, not to mention the giant pile of ambiguous UB that you risk whenever pointers and references interact that could so easily be avoided if Rust would just implement an -fno-strict-aliasing switch, but the devs refuse on what appears to be ideological grounds. The result is that for unsafe Rust, you get about the safety level of C much of the time, because RAII and many language facilities are not safe to use. Unsafe Rust is currently so dangerous that I feel much safer reaching for C++ for some of it. Mutable reference uniqueness, I think, should be enforced by the borrow checker and NOT by pain of inescapable possible undefined behavior at the assembler level.
Now for C++.
C++ is lacking a LOT of useful safety features that Rust comes with baked in, such as Mutexes owning their data, the borrow checker, a good, fast atomic reference counting type, and things that translate to more safety indirectly, like algebraic enums, assignable and movable arrays, tuples built into the language, etc. Generics in Rust, however, are significantly more painful to write due to the lack of duck typing. Perhaps the Rust devs felt that duck typing was too "dangerous" for templates, but because they're statically evaluated, these issues almost never materialize, and so in practice duck typed templates are almost always superior to Rust's generics.
C++ is definitely more mature and pragmatic as a language, but Rust is probably better for systems programming overall, at least if they fix their goddamn unsafe UB stuff.
As for move semantics, that book isn't for "what you MUST do to keep things semi-safe!" though it contains some stuff to that effect. It's more about optimization and tricks from what I can see. Move semantics take a little while to wrap your head around, but once you know the basics of C++'s move semantics, you can pretty much figure out what's going to happen by looking at a class' definition briefly.