On my fantastic journey implementing WinLamb v2, I’m diving deep into C++20, grasping a lot of concepts I never understood before, and having a lot of fun along the way.
One of the things that I implemented was the idea of non-copyable and non-movable classes, at first, using macros. This felt inelegant, so I implemented P2895 paper with utility classes. It ultimately failed with the nested ListView classes, so I discarded the idea too.
My final solution was to = delete move constructor, which will prevent all copy and move. The hard rules are not particularly easy to memorize, so I’ll let them here for further reference:
- The two copy operations are independent. Declaring copy constructor does not prevent compiler to generate copy assignment and vice versa. (Same as in C++98.)
- Move operations are not independent. Declaring either one of them prevents the compiler to generate the other. (Different from copy operations.)
- If any of the copy operations is declared, then none of the move operations will be generated.
- If any of the move operations is declared, then none of the copy operations will be generated.
- If a destructor is declared, then none of the move operations will be generated. Copy operations are still generated for reverse compatibility with C++98.
- Default constructor generated only when no constructor is declared. (Same as in C++98.)
Example:
class Foo {
private:
Foo(Foo&&) = delete; // non-copyable, non-movable
};