In this blog we will learn what is std::move in c++ and where it is used.  In c++11 move semantics is one of the important feature.

Let us see its syntax

template <class T>
typename remove_reference<T>::type&& move (T&& arg) noexcept;

From its syntax we can say that it returns an rvalue reference to arg. so what is rvalue? rvalue is value whose address can not be obtained. For example int a = 3; 3 is a rvalue.

What does it do and what is advantage?

Let see a very simple example of std::move and its effects.

#include <iostream>
#include <utility> // for std::move
#include <vector>

using namespace std; // for simplicity

int main()
{
    vector<string> vec;
    string a{ "1" };
    string b{ "2" };
    vec.push_back(a); // copy of a 

    // print a , b and vector contents
    cout << a << " " << b << "\n";
    cout << vec[0];
    cout << "\n";
    // push b in vec using move
    vec.push_back(move(b)); // call move version of push_back

    // print a, b and vector contents
    cout << a << " " << b << "\n";
    cout << vec[0] << " " << vec[1];
    cout << "\n";
    return 0;
}

Output:

1 2
1
1
1 2

From the output it is clear that when we use vec.push_back(move(b)); The vector calls move version of its push_back operation. Also look at the output.

after vec.push_back(move(b));

cout << a << ” ” << b << “\n”; it’s output is

1

that is b is not being printed. so when we use std::move(b) , the b no longer contains its value or content. So std::move is useful because it does not

  • Make a copy of the argument
  • Call the copy constructor
  • Change the argument object

 

Let us elaborate the concept of move semantics std::move.

Let us take an example.

#include <iostream>
#include <utility> // for std::move
#include <vector>

using namespace std; // for simplicity

class Myvector
{
public:
    vector<string> names;
public:
    void add_name(const string name)
    {
        names.push_back(name);
    }
    Myvector() 
    { 
        cout << "constructor\n"; 
    }
    virtual ~Myvector() 
    { 
        cout << "destructor\n"; 
    }
    //copy constructor
    Myvector(Myvector& myvec)
    {
        cout << "copy constructor\n";
        for (int i=0; i < myvec.size(); i++)
        {
            names.push_back(myvec.names[i]);
        }
    }
    size_t size() { return names.size(); }
};

int main()
{
    Myvector myvec;
    myvec.add_name("Mr. beans");
    myvec.add_name("Mr. X");
    myvec.add_name("Mr. Y");

    Myvector myvec_1 (myvec); // it will call copy constructor of Myvector class
}

 

In the above example , myvec_1 and myvec , both of the object will hold same contents. when we make an object myvec_1(myvec) , copy constructor of the class Myvector is called.

Suppose you want to make object myvec_1 , but you do not want object myvec to hold its contents. How will you achieve?

We achieve by using c++11 move semantics. We will provide a new move constructor to the class Myvector. and instead of invoking copy constructor we will use std::move. std::move will invoke move constructor of the class myvector.

#include <iostream>
#include <utility> // for std::move
#include <vector>

using namespace std; // for simplicity

class Myvector
{
public:
    vector<string> names;
public:
    void add_name(const string name)
    {
        names.push_back(name);
    }
    Myvector() 
    { 
        cout << "constructor\n"; 
    }
    virtual ~Myvector() 
    { 
        cout << "destructor\n"; 
    }
    //copy constructor
    Myvector(Myvector& myvec)
    {
        cout << "copy constructor\n";
        for (int i=0; i < myvec.size(); i++)
        {
            names.push_back(myvec.names[i]);
        }
    }

    Myvector(Myvector&& myvec)
    {
        cout << "move constructor\n";
        for (int i = 0; i < myvec.size(); i++)
        {
            names.push_back(move(myvec.names[i]));
        }
    }
    size_t size() { return names.size(); }
};

int main()
{
    Myvector myvec;
    myvec.add_name("Mr. beans");
    myvec.add_name("Mr. X");
    myvec.add_name("Mr. Y");

    Myvector myvec_1 (move(myvec)); // it will call move constructor of Myvector class

}

Now myvec object will no longer hold its contents.

Reference

https://stackoverflow.com/questions/3413470/what-is-stdmove-and-when-should-it-be-used

http://www.cplusplus.com/reference/utility/move/

Learn Modern C++ (C++11/C++14) Programming



Related Contents to follow