std move () : How this template function works?

Share the Article

The std::move( ) is a function template which perform static casts. The std::move( ) unconditionally casts its argument (an L-value or R-value) to an R-value. This template function takes a reference to an object (using a universal reference parameter) and it returns a R-value reference to the same object.

Example,

int x = 9; int && y = std::move(x); //Move taking L-value argument //& returning R-value int && z = std::move(4); //Move taking R-value argument //& returning R-value auto up1 = std::make_unique<int>(); std::unique_ptr<int> up2 = std::move(up1); //Move taking unique_ptr //& returning R-value of data

std::move does not move anything but it simply cast its argument to an R-value. Please note that everything happens only in compile time.

The simplest implementation of move is as follows:

template <typename T> typename std::remove_reference<T>::type&& move(T&& param) { using ReturnType = typename std::remove_reference<T>::type&&; return static_cast<ReturnType>(param); }
  • The parameter type is T&& (universal reference), which means it accepts both L-value and R-value arguments.
  • The “&&” part of the function’s return type means that std::move returns only an r-value reference.
  • The function uses typename because, we are using a datatype inside a template class T (dependent type)
using ReturnType = typename std::remove_reference<T>::type&&;

The funciton uses remove_reference because this ensures that whatever is the calling type (L-value or R-value), the return type always correspond to R-value of basic type.

The std::remove_reference template class is part of C++ library, however, we can easily implement this in following way:

template <class T> struct remove_reference { typedef T type; }; template <class T> struct remove_reference<const T> { typedef const T type; }; template <class T> struct remove_reference<T&> { typedef T type; }; template <class T> struct remove_reference<const T&> { typedef const T type; }; template <class T> struct remove_reference<T&&> { typedef T type; }; template <class T> struct remove_reference<const T&&> { typedef const T type; };

Code Example: Demonstration of local implementation of move function

#include <iostream> using namespace std; template <typename T> typename std::remove_reference<T>::type&& my_move(T&& param) { using ReturnType = typename std::remove_reference<T>::type&&; return static_cast<ReturnType>(param); } void check(int& a) //L-value version { cout << "L-value check() called" << endl; } void check(int&& a) //R-value version { cout << "R-value check() called" << endl; } int main() { check(5); //Calls check(&&) int w; check(w); //Calls check(&) check(my_move(w)); //Calls check(&&) return 0; }

The output is:

R-value check() called L-value check() called R-value check() called

Main Funda: std::move( ) does not move anything, it simply cast anything to its correspoding R-value at compile time

Related Topics:

 What are the drawbacks of using enum ?
Which member functions are generated by compiler in class?
How to stop compiler from generating special member functions?
Compiler Generated Destructor is always non-virtual
How to make a class object un-copyable?
Why virtual functions should not be called in constructor & destructor ?
Explaining C++ casts
How pointer to class members are different ?
How std::forward( ) works?
What is reference collapsing?
How std::move() function works?
How delete keyword can be used to filter polymorphism
Rule of Three

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *