What is std::move(), and when should it be used?

后端 未结 8 1984
粉色の甜心
粉色の甜心 2020-11-22 08:27
  1. What is it?
  2. What does it do?
  3. When should it be used?

Good links are appreciated.

8条回答
  •  悲&欢浪女
    2020-11-22 08:59

    1. "What is it?"

    While std::move() is technically a function - I would say it isn't really a function. It's sort of a converter between ways the compiler considers an expression's value.

    2. "What does it do?"

    The first thing to note is that std::move() doesn't actually move anything. It changes an expression from being an lvalue (such as a named variable) to being an xvalue. An xvalue tells the compiler:

    You can plunder me, move anything I'm holding and use it elsewhere (since I'm going to be destroyed soon anyway)".

    in other words, when you use std::move(x), you're allowing the compiler to cannibalize x. Thus if x has, say, its own buffer in memory - after std::move()ing the compiler can have another object own it instead.

    You can also move from a prvalue (such as a temporary you're passing around), but this is rarely useful.

    3. "When should it be used?"

    Another way to ask this question is "What would I cannibalize an existing object's resources for?" well, if you're writing application code, you would probably not be messing around a lot with temporary objects created by the compiler. So mainly you would do this in places like constructors, operator methods, standard-library-algorithm-like functions etc. where objects get created and destroyed automagically a lot. Of course, that's just a rule of thumb.

    A typical use is 'moving' resources from one object to another instead of copying. @Guillaume links to this page which has a straightforward short example: swapping two objects with less copying.

    template 
    swap(T& a, T& b) {
        T tmp(a);   // we now have two copies of a
        a = b;      // we now have two copies of b (+ discarded a copy of a)
        b = tmp;    // we now have two copies of tmp (+ discarded a copy of b)
    }
    

    using move allows you to swap the resources instead of copying them around:

    template 
    swap(T& a, T& b) {
        T tmp(std::move(a));
        a = std::move(b);   
        b = std::move(tmp);
    }
    

    Think of what happens when T is, say, vector of size n. In the first version you read and write 3*n elements, in the second version you basically read and write just the 3 pointers to the vectors' buffers, plus the 3 buffers' sizes. Of course, class T needs to know how to do the moving; your class should have a move-assignment operator and a move-constructor for class T for this to work.

提交回复
热议问题