How were move semantics addressed before C++11?

折月煮酒 提交于 2021-02-18 02:29:19

问题


I've been reading up on move semantics lately and how it was introduced into C++11. The main gist is that programs could become more efficient by creating objects by 'stealing' pointers to temporary objects. This is much more efficient than doing a deep copy of the temporary object to create new objects.

In C++11 (and onward), this is achieved with the use of rvalue references. All temporary objects (objects that don't have a known place within your programs memory) are considered rvalues. Specifically, class constructors could now be overloaded to accept rvalue references.

So I'm curious, how was this problem of 'expensive temporary object copy' addressed prior to C++11?


回答1:


The main way this was done was via std::swap. std::swap could be overloaded/specialized for types where it could be executed more efficiently than the default "swap via a temporary variable" to instead perform a shallow swap.

Often data types would provide a swap() member function that could be used by this overload to access the private internals of the data type. (For example; see std::vector::swap)

For example; to "move" an element into a vector, the following code could be used:

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

To return an element via "move", the following code could be used:

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.
}

I don't have a reference for this, but I believe standard algorithms were allowed/encouraged to use std::swap for this purpose.

Also, if you were feeling like you wanted to do things the C++11 way, you could also use boost::move, which provides an emulation of the C++11 move semantics in C++03 (though it technically violates strict aliasing and so has undefined behavior).



来源:https://stackoverflow.com/questions/41031592/how-were-move-semantics-addressed-before-c11

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!