1

I have the following program:

#include <vector>
#include <cassert>

class NoCopy {
public:
    explicit NoCopy(int d) : data(d) {}

    [[noreturn]] NoCopy(const NoCopy& other) : data(other.data) {
        assert(false); // Attempted to copy
    }

    [[noreturn]] NoCopy& operator=(const NoCopy& other) {
        assert(false); // Attempted to copy
    }

    NoCopy(NoCopy&& other) {
        assert(!other._movedFrom); // NoCopy should not have been moved from twice
        other._movedFrom = true;
        data = other.data;
    }

    NoCopy& operator=(NoCopy&& other) {
        assert(!other._movedFrom); // NoCopy should not have been moved from twice
        other._movedFrom = true;
        data = other.data;
        return *this;
    }

    // Just some data so that we can assert on it's contents.
    int data;

private:
    bool _movedFrom = false;
};

int main() {
    std::vector<NoCopy> v3;
    v3.reserve(3);
    v3.emplace_back(6);
    v3.emplace_back(7);
    v3.emplace_back(8);

    std::vector<NoCopy> v4;
    std::move(v3.begin(), v3.end(), std::back_inserter(v4));
    assert(v4[0].data == 6);
    assert(v4[1].data == 7);
    assert(v4[2].data == 8);
    return 0;
}

I would expect the std::move line to call the move constructor of the instances of NoCopy, but instead the program asserts on line 9 (copy constructor). What am I doing wrong?

Drew
  • 12,578
  • 11
  • 58
  • 98

1 Answers1

0

As v4 expands when you insert into it, it needs to copy its contents. That's where the copy-construction comes from.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621