基于范围的std :: move意外调用复制构造函数

时间:2019-07-11 18:45:29

标签: c++ c++17 move

我有以下程序:

#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;
}

我希望std::move行能够调用NoCopy实例的move构造函数,但是程序会在第9行断言(复制构造函数)。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

v4插入时展开时,它需要复制其内容。这就是复制构造的来源。