4 ms·
> From my five years of learning and using C++, I still have no clear picture how move semantics and rvalue references work. ... The complexity created by impli
by 0815test 7y ago
> From my five years of learning and using C++, I still have no clear picture how move semantics and rvalue references work. ... The complexity created by implicit and explicit copy/move constructors is just insanity for me...
This is the best argument for move from C++ to Rust instead. No "move constructors" whatsoever, move semantics are the default and are always performed via a trivial memcpy. There are explicit .clone() operations, like in some other languages, or the move construct can implicitly copy when the type is a POD-equivalent that makes this possible (identified by the Copy "trait"). Very simple, and nothing like the whole C++ move mess.
- 72deluxe 7y agoSo what if I have an object that has a pointer to another object? memcpy is not what I want in that instance.
- damnyou 7y agoIf you mean intrusive data structures, Rust just doesn't support them. Everyone still manages to write software in Rust just fine. (There's some early support for immovable data with `Pin`, but that's only exposed via async/await at the moment.) Move constructors are one of the worst parts of C++ and being able to write movable, intrusive data structures is absolutely not worth the cost. If you do need one, Rust shows that it's better to sacrifice movability than introduce move constructors. This is not uncommon -- there are some things you can do in C++ that you simply cannot do in Rust (either safely, or at all). Usually there's another, better way to achieve the same overall goals.
- asveikau 7y ago> Move constructors are one of the worst parts of C++ Move constructors fix a narrow problem, which is, when you have something like a vector append, how do you copy over all the previous elements as a "shallow" copy rather than a deep one? In C with realloc(), it's just assumed that memcpy works for that. With C++03 and earlier copying the elements could very well end up duplicating everything on the heap for no reason, then discarding the old copy. How does rust do this? What I am reading from googling is that every assignment is a move?
- damnyou 7y agoYes, every assignment of a non-Copy type is a move. (Copy types are basically primitive ones like ints, so not vectors etc.) The compiler prevents you from using the old variable at that point. Since Rust always enforces that a move is a memcpy, a vector reallocation is just a realloc() like in C.
- steveklabnik 7y agoSafe rust may not support them, but you can use unsafe to write them. There’s a bunch of implementations of intrusive collections on crates.io. Also, Pin is stable but async/await is not, so you’re backwards there :)
- tene 7y agoAssuming struct A has a reference to struct B, memcpy is a fine way to move struct A, and struct B cannot be moved while borrowed. Here's an example I put together demonstrating this: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3a0bfadb6c196cde8588d8cd0fab8a91 https://play.rust-lang.org/?version=stable&mode=debug&editio...
- Retra 7y agoRust doesn't move through the pointer, it moves only the pointer, which should be perfectly fine.