4

I am learning CPP++14 move semantics.While writing a small code I observed some weird behavior. I am moving vector of unique ptr to a function using r-value refrence. on debuuging I found that the changes are being applied to the moved object also. Why am I observing this hcnage even the object is moved? Whats does the move do in following code?

void func(std::vector<std::unique_ptr<int>> && vect) {
    vect.emplace_back(std::move(std::make_unique<int>(3)));
    return ;
}

int  main() {
    std::vector<std::unique_ptr<int>> a;
    func(std::move(a));
    cout<<(*(a[0]))<<endl;
    return 0;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 2
    You are not moving anything. You are just passing the object by rvalue reference. The move is no more then a cast in your code. – super Sep 04 '20 at 16:08
  • @super Don't answer in comments please if the quesiton is useful and _on-topic_. – πάντα ῥεῖ Sep 04 '20 at 16:09
  • 4
    [This](https://stackoverflow.com/questions/3106110/what-is-move-semantics) should help your understanding of move semantics. You also might want to consider getting yourself a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – NathanOliver Sep 04 '20 at 16:10
  • @πάνταῥεῖ - if you write a short answer it gets automatically converted to a comment. – Den-Jason Sep 04 '20 at 16:28
  • @Den-Jason Ah ty. I didn't know that. Must have been changed recently. I was a year off to the meta boot camp ;-) – πάντα ῥεῖ Sep 04 '20 at 16:29
  • @πάνταῥεῖ If it happens, it's not automatic. Could be reviews or mods. – user4581301 Sep 04 '20 at 16:52

1 Answers1

5

Whats does the move do in following code?

Move operation is not performed in func(std::move(a)); in fact, std::move just performs conversion and produces an rvalue (xvalue) expression, which is just bound to the rvalue reference parameter vect of func. Then any modification on vect inside func has effect on the argument (i.e. a) too, they refer to the same object.

In particular, std::move produces an xvalue expression that identifies its argument t. It is exactly equivalent to a static_cast to an rvalue reference type.

If you change the parameter to pass-by-value, then you'll see move operation is performed. And given the usage you showed, just pass-by-lvalue-reference seems less confusing (and no need to use std::move on argument again).

BTW: In vect.emplace_back(std::move(std::make_unique<int>(3))); the usage of std::move is superfluous, std::make_unique<int>(3) been an rvalue expression.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • It converts it to an rvalue reference, not an rvalue. All reference types are lvalues. – NathanOliver Sep 04 '20 at 16:11
  • 1
    @NathanOliver value category is a property of expressions, not types. `move(a)` as an expression is an rvalue. – dyp Sep 04 '20 at 16:11
  • Can this be considered as good practice to use this approach ? Will this create any memory related issues like cleaning memory and leakages? – asheesh kumar singhal Sep 04 '20 at 16:19
  • 1
    @asheeshkumarsinghal Your code is fine for the usage you showed; it's just confusing. Just pass-by-lvalue-reference seems better here. – songyuanyao Sep 04 '20 at 16:22
  • ok. L value ref also gives the same result. However, Since its contains unique pointers shouldn't "a" be moved? – asheesh kumar singhal Sep 04 '20 at 16:27
  • 2
    @asheeshkumarsinghal If you take the vector by value it will be moved. Passing something by reference will not move it. A reference is just something that refers to the original. – super Sep 04 '20 at 16:30
  • 1
    @asheeshkumarsinghal No, it has nothing to do with what `a` is for this case. It's just bound to the reference parameter. If you create a new object which is copied from an rvalue, move operation happens. – songyuanyao Sep 04 '20 at 16:31
  • Ah! Understood. And Since 'vect' is simply a reference to 'a', it will have no effect on its lifetime. Also 'vect' get destroyed/ freed as soon as function completes its execution. Am I correct? – asheesh kumar singhal Sep 04 '20 at 16:38
  • 1
    @asheeshkumarsinghal Yes it's just a reference, and get destroyed when get out of the function. Note that the object referenced by it (i.e. `a`) doesn't get destroyed. – songyuanyao Sep 04 '20 at 16:40