c ++通过移动而不是复制来交换数组元素

时间:2017-02-03 22:59:44

标签: c++ arrays

是否可以通过简单地将两个元素移动到新索引而不是具有临时值的昂贵副本来交换数组的两个元素?

我有这段代码:

struct Piece {
    int index;
    int type;
    int square;

    Piece() {}
    ~Piece() {}
    Piece(Piece& piece) {
        printf("copy");
    }
    Piece(Piece&& piece) {
        printf("move");
    }

    void operator=(Piece& piece) {
        printf("copy1");
        int temp = square;
        square = piece.square;
        piece.square = temp;
    }
    void operator=(Piece&& piece) {
        printf("move1");
    }
};

int main() {
    Piece* pieces = new Piece[10];
    Piece* sliders = new Piece[10];

    pieces[0] = {};
    pieces[0].square = 50;
    pieces[1] = {};
    pieces[1].square = 20;

    Piece temp = pieces[0];
    pieces[0] = pieces[1];
    pieces[1] = temp;

    cout << pieces[1].square << " " << pieces[0].square;
    char test;
    cin >> test;
}

初始化时始终打印“move”,与temp交换时打印“copy1”。 有没有办法通过移动来做同样的事情而不使用指针数组?

请忽略此代码的不良风格。

4 个答案:

答案 0 :(得分:8)

使用std::swap ...

std::swap(pieces[0], pieces[1]);

你可以等同地写:

Piece temp = std::move(pieces[0]);
pieces[0] = std::move(pieces[1]);
pieces[1] = std::move(temp);

std::swap更简洁。

答案 1 :(得分:2)

选项1:使用std :: swap。

std::swap<Piece>(pieces[0], pieces[1])

选项2:使用std :: move。

Piece temp = std::move(pieces[0]);
pieces[0] = std::move(pieces[1]);
pieces[1] = std::move(temp);

此外,让你的移动操作不会抛出。

答案 2 :(得分:2)

由于您的类的数据只是一些标量值,因此您是否通过临时交换它们并不重要。也就是说,如果您放弃对打印代码的调用,并且优化编译,则无关紧要。无论如何,它都会通过寄存器发生。

你应该仍然使用std::swap(),因为这是“正确的方法”。如果你让你的Piece课更多参与,它实际上会产生一些影响......

答案 3 :(得分:0)

  

是否可以通过简单地将两个元素移动到新索引而不是具有临时值的昂贵副本来交换数组的两个元素?

否定给定的结构件。当您可以将指针分配(复制,交换)指向大尺寸和/或堆分配的数据时,您将受益于移动语义。节省来自复制指针而不是更大的数据和/或避免内存释放/分配,这可能比复制大型数据对象需要更多的CPU周期。