C++ the good parts — std::swap

As you know for the simple pod-like type we have used above, the compiler has generated all the necessary scaffolding, constructors and the rest. And the whole section was almost boring?

Let us create and use the simple but nontrivial type to analyze moving and swapping in scenarios where native pointers are the members.

Remember: we have left it to the trusty C++ compiler to generate implicit destructors and assignment operators. All six of them. Good. Let us do the simple value move first

The result is an application crash because of an Access violation. Let’s repeat the above but with comments

The cause: Implicitly generated move ctor moved over just the pointer from the specimen, not the actual heap-allocated data.  Thus resulting in two pointers to the same memory.  Thus the second free from the second destructor provoked a crash. So how do we stop that and make not_a_pod movable?

C++20 has a concept std::movebale which immediately revel the requirements. Thus we need to add the move constructor.

Which as we see, in turn, provoked the need for two constructors, move constructor and the swap()  friend, where we implement data pointers rewiring.

Basically, we have added a user-defined move constructor, swap and two constructors. And move worketh after these changes. As did the value swapping too.

Data has stayed where it was. We are just pointing to it from the object moved to, and detach the point for the object moved from.

Above using is the standard idiom to pacify the ADL.  What about pointer tests? Let’s try and move the pointer.

And swapping the pointers worketh too

That is an absolutely minimal non-trivial type of implementation that is swappable. Please observe what scaffolding we had to implement to have moved off our type of work.

There is the fully functioning Godbolt implementation. Please copy it into your favourite IDE, compile and follow through the debugger.  At least few times. Compiled with all the warnings included, as C++17  and with maximal optimizations. For GCC or clang that means: -std=c++17 -Wall -O3.

Conclusion

C++ terminology is important and hard to grasp immediately. Flexibility brings complexity. Modern C++ is very flexible. That means your move implementation can be very finely tuned for non-trivial types you create…

Modern C++ is built on a few of these mechanisms. I do hope by reading this long post you gained a better understanding of the intricacies of swapping, moving and value-based semantics.

Appendix A

(please go to next page)