To answer what I think is the heart of your question:
The question make sense for developing, say, std::variant-like or
std::tuple-like class
There are 3 kinds of class-types that are of concern here viz.
- Owner Types
- Regular Types
- Other types (Functions, Mutexes)
In the following assume both assign & construct suffixes are present for move/copy. I will refer to non-trivial operations as clone-:
Owner Types: These are Movable & Clone-able ( deep copy or shallow copy are the choices to be made)
Stereotypical examples are std::unique_ptr, std::shared_ptr
Regular Types(int-like): These are Movable & Copy-able.
Stereotypical examples are int, std::vector.
A lot more details for these types can be found at What is a "Regular Type" in the context of move semantics? & in Elements Of Programming.
Other types (Functions, Mutexes etc.): These types refuse to be put into one of the clean classes above eg. Functions may refer to a pointer, a lambda with captures etc.
As far as all the other combinations of trivially copy-able/movable are concerned while you can create such classes I think they are more like curiosities rather things you will see in any useful scenario.
I have put std::vector in Regular Types rather than Owner Types even though std::vector
manages memory since its interface is designed to be as close to a regular type as possible. You can often design a Regular interface for a type which is superficially non-regular. In such scenarios reasoning about code is easier if you use a regular interface.