copy vs std::move for ints

前端 未结 4 1620
一生所求
一生所求 2020-12-08 14:20
  • What\'s difference between default copy and std::move in that example?
  • After move the object is there any dependence between new and old ones?
相关标签:
4条回答
  • 2020-12-08 15:07

    What's difference between default copy and std::move in that example?

    There is no difference. Copying something satisfies the requirements of a move, and in the case of built-in types, move is implemented as a copy.

    After move the object is there any dependence between new and old

    No, there are no dependencies. Both variables are independent.

    0 讨论(0)
  • 2020-12-08 15:07

    To expand on the other poster's answer, the move-is-a-copy paradigm applies to all data structures composed of POD types (or composed of other types composed of POD types) as well, as in this example:

    struct Foo
    {
        int values[100];
        bool flagA;
        bool flagB;
    };
    
    struct Bar
    {
        Foo foo1;
        Foo foo2;
    };
    
    int main()
    {
        Foo f;
        Foo fCopy = std::move(f);
        Bar b;
        Bar bCopy = std::move(b);
        return 0;
    }
    

    In the case of both Foo and Bar there is no meaningful way to move the data from one to another because both are ultimately aggregates of POD types - none of their data is indirectly owned (points to or references other memory). So in these cases, the move is implemented as a copy and originals (f, b) remain unaltered after the assignments on the std::move() lines.

    Move semantics can only be meaningfully implemented with dynamically allocated memory or unique resources.

    0 讨论(0)
  • 2020-12-08 15:15

    Using std::move just changes an lvalue to an xvalue, so it is eligible for use with move constructors and move assignment operators. These do not exist for built-in types, so using move makes no difference in this example.

    0 讨论(0)
  • 2020-12-08 15:17

    In this example, there is no difference. We will end up with 3 ints with value 100. There could definitely be a difference with different types though. For instance, let's consider something like vector<int>:

    std::vector<int> a = {1, 2, 3, 4, 5}; // a has size 5
    auto a_copy = a;                      // copy a. now we have two vectors of size 5
    auto a_move = std::move(a);           // *move* a into a_move
    

    The last variable, a_move, takes ownership of a's internal pointers. So what we end up with is a_move is a vector of size 5, but a is now empty. The move is much more efficient than a copy (imagine if it was a vector of 1000 strings instead - a_copy would involve allocating a 1000-string buffer and copying 1000 strings, but a_move just assigns a couple pointers).

    For some other types, one might be invalid:

    std::unique_ptr<int> a{new int 42};
    auto a_copy = a;            // error
    auto a_move = std::move(a); // OK, now a_move owns 42, but a points to nothing
    

    For many types, there's no difference though:

    std::array<int, 100> a;
    auto a_copy = a;            // copy 100 ints
    auto a_move = std::move(a); // also copy 100 ints, no special move ctor
    

    More generally:

    T a;
    auto a_copy = a;            // calls T(const T& ), the copy constructor
    auto a_move = std::move(a); // calls T(T&& ), the move constructor
    
    0 讨论(0)
提交回复
热议问题