Does D have something akin to C++0x's move semantics?

前端 未结 5 1734
予麋鹿
予麋鹿 2020-12-15 03:45

A problem of \"value types\" with external resources (like std::vector or std::string) is that copying them tends to be quite expensive, a

5条回答
  •  囚心锁ツ
    2020-12-15 04:15

    I think all answers completely failed to answer the original question.

    First, as stated above, the question is only relevant for structs. Classes have no meaningful move. Also stated above, for structs, a certain amount of move will happen automatically by the compiler under certain conditions.

    If you wish to get control over the move operations, here's what you have to do. You can disable copying by annotating this(this) with @disable. Next, you can override C++'s constructor(constructor &&that) by defining this(Struct that). Likewise, you can override the assign with opAssign(Struct that). In both cases, you need to make sure that you destroy the values of that.

    For assignment, since you also need to destroy the old value of this, the simplest way is to swap them. An implementation of C++'s unique_ptr would, therefore, look something like this:

    struct UniquePtr(T) {
        private T* ptr = null;
    
        @disable this(this); // This disables both copy construction and opAssign
    
        // The obvious constructor, destructor and accessor
        this(T* ptr) {
            if(ptr !is null)
                this.ptr = ptr;
        }
    
        ~this() {
            freeMemory(ptr);
        }
    
        inout(T)* get() inout {
            return ptr;
        }
    
        // Move operations
        this(UniquePtr!T that) {
            this.ptr = that.ptr;
            that.ptr = null;
        }
    
        ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no "ref" on "that"
            swap(this.ptr, that.ptr); // We change it anyways, because it's a temporary
            return this;
        }
    }
    

    Edit: Notice I did not define opAssign(ref UniquePtr!T that). That is the copy assignment operator, and if you try to define it, the compiler will error out because you declared, in the @disable line, that you have no such thing.

提交回复
热议问题