在C++ 11之前如何解决移动语义?

Izz*_*zzo 5 c++ c++03

我最近一直在阅读移动语义,以及它是如何被引入C++ 11的.主要的要点是,通过"窃取"临时对象的指针来创建对象,程序可以变得更有效率.这比执行临时对象的深层复制以创建新对象更有效.

在C++ 11(及以后)中,这是通过使用rvalue引用来实现的.所有临时对象(程序内存中没有已知位置的对象)都被视为右值.具体来说,类构造函数现在可以重载以接受rvalue引用.

所以我很好奇,在C++ 11之前,这个"昂贵的临时对象复制"问题是如何解决的?

Man*_*rse 6

这样做的主要方式是通过std::swap.std::swap可以重载/专用于类型,它可以比默认的"通过临时变量交换"更有效地执行,而不是执行浅交换.

通常,数据类型将提供swap()可由此重载使用的成员函数来访问数据类型的私有内部.(例如;参见std :: vector :: swap)

例如; 要将元素"移动"到a vector,可以使用以下代码:

class MyListOfVectors {
    private:
    //using `std::vector<int>` as an example of a "movable" type.
    std::vector<std::vector<int>> list;
    public:
    void emplace_back(std::vector<int> &n) {
        using std::swap;
        list.push_back(std::vector<int>());
        swap(list.back(), n);
        //(possibly add something to rollback the `push`
        // in case swap fails; to provide the strong
        // exception guarantee)
    }
};
Run Code Online (Sandbox Code Playgroud)

要通过"move"返回元素,可以使用以下代码:

std::vector<int> MyListOfVectors::pop_back() {
    using std::swap;
    std::vector<int> r;
    swap(list.back(), r);
    list.pop_back();
    return r; //Trust in copy elision to avoid any actual copies.
}
Run Code Online (Sandbox Code Playgroud)

我没有这方面的参考,但我相信允许/鼓励标准算法std::swap用于此目的.

另外,如果你觉得你想用C++ 11方式做事,你也可以使用boost :: move,它提供了C++ 03中C++ 11移动语义的模拟(虽然它在技术上违反了严格别名,因此有未定义的行为).