Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does std::move work with lvalue references? How does std::move work on standard containers?

#include <vector>

struct A { int a[100]; };

void foo (const A& a) {
  std::vector<A> vA; 
  vA.push_back(std::move(a));  // how does move really happen?
}

int main () {
  A a;
  foo(a);
}

The above code compiles fine. Now everywhere it's written that move avoids copying.
Following are my queries:

  1. Does the move really work when one deals with a lvalue [non]-const reference?
  2. Even with "rvalue reference", how is the copy avoided when the object is inserted into a standard container like above?

e.g.

void foo (A&& a) {  // suppose we invoke this version
  std::vector<A> vA; 
  vA.push_back(std::move(a));  // how copy is avoided?
}
like image 898
iammilind Avatar asked Aug 12 '16 11:08

iammilind


People also ask

What does std :: move () do?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another 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.

Can you move a reference C++?

In C++11, the answer is--you can! That's what rvalue references and move semantics are for! Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.

Is std :: move necessary?

A: You should use std::move if you want to call functions that support move semantics with an argument which is not an rvalue (temporary expression).

What is the difference between std :: forward and std :: move?

std::move takes an object and casts it as an rvalue reference, which indicates that resources can be "stolen" from this object. std::forward has a single use-case: to cast a templated function parameter of type forwarding reference ( T&& ) to the value category ( lvalue or rvalue ) the caller used to pass it.


1 Answers

Created a snippet to show it. Though in your example default constructor will be called, but you get the idea.

#include <vector>
#include <iostream>

struct A { 
  int a[100];
  A() {}
  A(const A& other) {
    std::cout << "copy" << std::endl;
  }
  A(A&& other) {
    std::cout << "move" << std::endl;
  }
};

void foo(const A& a) {
  std::vector<A> vA; 
  vA.push_back(std::move(a));
}

void bar(A&& a) {
  std::vector<A> vA; 
  vA.push_back(std::move(a));
}

int main () {
  A a;
  foo(a);            // "copy"
  bar(std::move(a)); // "move"
}
like image 160
laike9m Avatar answered Oct 10 '22 08:10

laike9m