On Tue, Mar 1, 2022 at 5:26 PM Andreas Ringlstetter via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
> The larger picture here seems to be an effort to make move semantics friendlier and easier to use. I began an informal survey on open-std of papers on move semantics.

Move semantics so far suffer in 2 domains:
- There is no way in the language standard to notify the compiler that
an object is trivially deconstrutible as it hasn't been touched after
a specific class of constructor
- There is no way to tell the compiler that an object which has just
been moved shall be implicitly assumed to have returned to such a
pristine state.
Is this limited to move constructors? No, a quick thought experiment
shows this is actually universally applicable:

struct unique_ptr {
    unique_ptr() noexcept [[post=trivial]] { /* non-trivial constructor */};
    unique_ptr(unique_ptr&& [[post=trivial]] other);
    ~unique_ptr() [[post=trivial]] { /* non-trivial destructor */};
    void reset() [[post=trivial]];

Andreas: This is a philosophically interesting idea. However, it suffers from the same general problem as Niall's [[move_relocates]] except worse. The problem is that it enables a lot of satisfying bookkeeping, but doesn't actually enable the practical optimizations that we care about w.r.t. trivial relocation. Here are some examples:

(1) When we reallocate a std::vector<T>, can we just memcpy the bytes from the old buffer into the new buffer? or must we tediously call some user-defined operation on T in a loop? Marking your move-ctor [[post=trivial]] tells me that once I've tediously called the move-ctor in a loop, I can skip calling the destructor in a loop; but it still doesn't tell me that I can memcpy in the first place.

(2) When we put a T into a std::any, can its "relocate" affordance use a common memcpying codepath? or must we generate a "relocate" lambda that type-erases the move-ctor and dtor of this specific T? Marking your move-ctor [[post=trivial]] doesn't tell me that your relocation operation is tantamount to memcpy; it doesn't actually tell me anything about the behavior of your relocation operation. I still have to generate a lambda to type-erase it; I can't use a common codepath.

(3) When we swap two objects of type T, can we just swap their bytes? or must we call some user-defined operation(s) on T?  This affects std::rotate, std::partition, std::sort, and many other STL algorithms.