Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to call the default move operator from a non-default one?

I have this class:

struct Handle
{
    int* ptr_to_something;
    void operator=(Handle&& other)
    {
        ptr_to_something = other.ptr_to_something;
        this->member1 = other.member1;
        this->member2 = other.member2;
        this->member3 = other.member3;
        
        other.ptr_to_something = nullptr;
        
    }
    
    int member1;
    int member2;
    int member3;
};

What I hate is possibility that new members might be added, and I’ll have to remember to add them to the operator. Is there possibly a way I could call the default operator and then add that teensy little but that sets the other ptr to null after it?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can have a base class with a defaulted move operator:

struct HandlerBase {
    int* ptr_to_something;
    int member1;
    int member2;
    int member3;
};

struct Handler : HandlerBase {
    void operator=(Handler&& other) {
        HandlerBase::operator=(std::move(other));
        other.ptr_to_something = nullptr;
    }
};

Or you can make the defaulted move operator do what you want by making ptr_to_something a class whose operator= does what you want:

template<typename T>
struct PtrThatResetsOnMove {
    T* value;

    constexpr explicit(false) PtrThatResetsOnMove(T* value) noexcept : value(value) {}
    constexpr PtrThatResetsOnMove(PtrThatResetsOnMove&& other) noexcept : value(std::exchange(other.value, nullptr)) {}
    constexpr PtrThatResetsOnMove& operator=(PtrThatResetsOnMove&& other) noexcept {
        value = std::exchange(other.value, nullptr);
        return *this;
    }
    ~PtrThatResetsOnMove() = default;
};

struct Handler {
    PtrThatResetsOnMove<int> ptr_to_something;
    int member1;
    int member2;
    int member3;
};

Or you can put the other members in a different class with a defaulted operator:

struct HandlerMembers {
    int member1;
    int member2;
    int member3;
};

struct Handler {
    int* ptr_to_something;
    HandlerMembers members;
    void operator=(Handler&& other) {
       ptr_to_something = other.ptr_to_something;
       members = std::move(other.members);
       other.ptr_to_something = nullptr;
    }
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading