1

I'm approaching C++ for the first time, and I'm reading The C++ Programming Language as a guide.

I understand the move semantics in principle, I want to know if I understand when they are used, but I don't really know how to test it by myself.

If I have this:

vector<int> a{1,2,3,4,5};
vector<int> b = a;

this is a (slow) copy. a as ha name and it's an lvalue (it can be modified), so the compiler copies it's content into b by allocating a new vector and copying each element one by one.

In this case:

vector<int> a{1,2,3,4,5};
vector<int> b = std::move(a);

I'm forcing a "to be" a rvalue (can't be modified) and it's content it's moved to b without overhead. (By the way, is std::move an expensive operation to perform?)

If I have a function that returns a vector (foo()) and I do this

b = foo();

When foo() returns the vector, I'm getting a move, because the returned value is an rvalue. Memory is allocated only once in foo(), when I declared the vector that will be returned.

When I'm using a constructor like this:

vector<Object> x{new Object(),new Object(),new Object()};

I'm still getting moves, since the results of those three new operations are rvalues, right?

x = new Object();

This would result in a move too, assuming whatever x type is, it has a move assignment.

In the case of a container that supports push_back() (or other similar operations), if I pass to push_back() an rvalue, there will be a move, otherwise a copy. Like:

vector<int> a{1,2,3,4,5};
b.push_back(a);
b.push_back(std::move(a));

in the second case, a will be appended to b with a move and not a copy. In the first case it will be a copy.

Another thing:

vector<int> a{1,2,3,4,5};
vector<int> b = std::move(a);

In this case a is "static" memory, not dynamically allocated. It's content is moved to b. Is a taking up any more memory that I would need to free somehow?

Thank you very much for your help!

Paul
  • 473
  • 6
  • 19
  • 6
    `std::move` has no overhead, it's a type cast. `std::move` in itself does not preform any work and does not make any change. However, the move assignment or move construction that it allows will have some overhead, typically a constant overhead. – François Andrieux Jul 04 '17 at 20:29
  • 6
    `vector x{new Object(),new Object(),new Object()};` is generally invalid. Your vector is declared to hold objects of type `Object` directly. But `new` evaluates to an `Object *` pointer. – AnT stands with Russia Jul 04 '17 at 20:29
  • @FrançoisAndrieux Understood, thanks. – Paul Jul 04 '17 at 20:31
  • @AnT You're right, thank you. – Paul Jul 04 '17 at 20:31
  • 2
    `vector a{1,2,3,4,5};` - `vector`s are _always_ dynamically allocated. If you move one vector to another, ownership of that dynamically allocated memory will probably be moved as well. You don't have to manually manage memory anyhow with `vector`s. – yeputons Jul 04 '17 at 20:33
  • 1
    `x = new Object();` - it's pointless to talk about move semantics here, because `new Object()` is a pointer, which is a very simple type. If you, however, write `x = Object()` or `x = foo()` instead, then move assignment will be performed (if it exists). – yeputons Jul 04 '17 at 20:34
  • 1
    The general understanding looks right, except for what's already covered in comments. – yeputons Jul 04 '17 at 20:35
  • @yeputons thank you very much. – Paul Jul 04 '17 at 20:48
  • VTC as unclear due to the problem with `new` , maybe you could rewrite that part of the question – M.M Jul 05 '17 at 04:22

0 Answers0