简体   繁体   中英

Can move object from vector A to vector B, but not from B to A?

I have a class which has a vector of objects. The objects in question have deleted copy constructors and copy assignment operators, and thus they have a move constructor and move assignment operator to allow them to be used with vectors. This class that holds the objects has append and extract methods which allow objects to be appended to the class' object vector from a buffer or extracted from the class' object vector to a buffer.

The object definition looks like this:

struct MyObject
{
    int width_ = 0;
    int height_ = 0;
    //etc...

    stImage() = default; 

    stImage(int width, int height, ...)
    {
        width_ = width;
        height_ = height;
        //etc...
    }

    stImage(const stImage& rhs) = delete;

    stImage& operator= (const stImage & rhs) = delete;

    stImage(stImage&& rhs) : width_(0), height_(0), ...
    {
        *this = std::move(rhs);
    }

    stImage& operator=(stImage&& rhs)
    {
        if (this != &rhs)
        {
            width_ = rhs.width_;
            height_ = rhs.height_;
            //etc...

            rhs.width_ = 0;
            rhs.height_ = 0;
            //etc...
        }
        return *this;
    }
};

The append methods compile:

void MyClass::append(MyObject * buffer)
{
    data_.push_back(std::move(*buffer));
}

void MyClass::append(Vector<MyObject> * buffer)
{
    for (int i = 0; i < (*buffer).size(); i++) 
    {
        data_.push_back(std::move((*buffer)[i]));
    }
 }

However, the extract method does not:

void MyClass::extract(it8 start, Length length, Vector<MyObject> * buffer) const
{
    for (it8 i = start; i < (start + length); i++) 
    {
        (*buffer).push_back(std::move(data_[i]));
    }
}

The error given is "C2280 'MyObject::MyObject(const MyObject &)': attempting to reference a deleted function"

I can't see why these two operations are functionally any different from each other. Any insight into why extract fails and append does not would be appreciated, and a way to make extract work would be even more so.

(Note: Vector here is a custom implementation of std::vector because Reasons, but as far as I'm aware, they function the same. If this is potentially the issue, and std::vector would be fine with append/extract as they stand, I guess I'll see if using it would be OK.)

extract is a const member function and in const member function every reference to member variables are consts. When you access to data_[i] the returning data type is const MyObject& .

std::move just cast it's input to a r-value reference and in your case the return type of std::move is const MyObject&& , but because object has const qualifier the chosen overload for push_back will be push_back(const T&) .

You can use const_cast to remove const from data_ , But it's not the best solution. Also mutable keyword can be used, but the best solution is to declare your function as non-const function because it's modifying object internal state.

Constness, I guess. 'extract' removes from data_, so can not be const.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM