Is it possible to std::move local stack variables?

后端 未结 2 1015
迷失自我
迷失自我 2021-01-31 09:25

Please consider the following code:

struct MyStruct
{
    int iInteger;
    string strString;
};

void MyFunc(vector& vecStructs)
{
    MyStr         


        
2条回答
  •  失恋的感觉
    2021-01-31 09:49

    First, std::move does not move, and std::forward does not forward.

    std::move is a cast to an rvalue reference. By convention, rvalue references are treated as "references you are permitted to move the data out of, as the caller promises they really don't need that data anymore".

    On the other side of the fence, rvalue references implicitly bind to the return value of std::move (and sometimes forward), to temporary objects, in certain cases when returning a local from a function, and when using a member of a temporary or a moved-from object.

    What happens within the function taking an rvalue reference is not magic. It cannot claim the storage directly within the object in question. It can, however, tear out its guts; it has permission (by convention) to mess with its arguments internal state if it can do the operation faster that way.

    Now, C++ will automatically write some move constructors for you.

    struct MyStruct
    {
      int iInteger;
      string strString;
    };
    

    In this case, it will write something that roughly looks like this:

    MyStruct::MyStruct( MyStruct&& other ) noexcept(true) :
      iInteger( std::move(other.iInteger) ),
      strString( std::move(other.strString) )
    {}
    

    Ie, it will do an element-wise move construct.

    When you move an integer, nothing interesting happens. There isn't any benefit to messing with the source integer's state.

    When you move a std::string, we get some efficiencies. The C++ standard describes what happens when you move from one std::string to another. Basically, if the source std::string is using the heap, the heap storage is transferred to the destination std::string.

    This is a general pattern of C++ containers; when you move from them, they steal the "heap allocated" storage of the source container and reuse it in the destination.

    Note that the source std::string remains a std::string, just one that has its "guts torn out". Most container like things are left empty, I don't recall if std::string makes that guarantee (it might not due to SBO), and it isn't important right now.

    In short, when you move from something, its memory is not "reused", but memory it owns can be reused.

    In your case, MyStruct has a std::string which can use heap allocated memory. This heap allocated memory can be moved into the MyStruct stored in the std::vector.

    Going a bit further down the rabbit hole, "Hello" is likely to be so short that SBO occurs (small buffer optimization), and the std::string doesn't use the heap at all. For this particular case, there may be next to no performance improvement due to moveing.

提交回复
热议问题