﻿# The std::move function

The _std::move_ function aims at implementing [move semantics](https://pvs-studio.com/en/blog/terms/6514/)\. The function receives a [forwarding reference](https://pvs-studio.com/en/blog/terms/6517/) to an object and returns an rvalue reference to this object\. One of the possible implementations of _std::move_ looks as follows:

```cpp
template<typename T>
std::remove_reference_t<T>&& move(T&& x) 
{
  return static_cast<std::remove_reference_t<T>&&>(x);
}
```

lvalue and rvalue references can be passed to the _std::move_ function, and an rvalue reference must be obtained as a result\. Therefore, to denote the return type, we first use the _std::remove\_reference\_t _trait, that simplifies the template type _T_ to a usual non\-reference type\. Then we explicitly add '&&'\. Let's take a look at the following code fragment:

```cpp
std::vector<int> &vec1 = DoSomeCalculations();
std::vector<int> vec2 = std::move(vec1);
```

Here's what we have here:

* An instance of the _std::move_ function is instantiated with  template type _T \= std::vector<int\> &_ \.
* This instance takes an argument of the _std::vector<int\> &_ type\. When trying to form an argument as an rvalue reference to _std::vector<int\> &_, the compiler uses reference collapse, and the result argument type is equivalent to _std::vector<int\> &_\. This is an lvalue reference to _vector<int\>_\.
* The _std::remove\_reference\_t_ trait returns the _std::vector<int\>_ type simplified to a non\-reference type\. '&&' is added to _std::vector<int\>_\. As a result, the return type of _std::vector<int\> &&_ is an rvalue reference to _vector<int\>_\.

Now let's consider the case when an rvalue reference is passed to _std::move_:

```cpp
std::vector<int> &&vec1 = DoAnotherCalculations();
std::vector<int> vec2 = std::move(vec1);
```

Here's what happens:

* An instance of the _move_ function with template type_ T \= std::vector<int\>_ is instantiated\.
* This instance receives an argument of the _std::vector<int\> && _type\. It is an rvalue reference on _vector<int\>_\.
* The _std::remove\_reference\_t_ trait returns the _std::vector<int\>_ type simplified to a non\-reference type\. '&&' is added to _std::vector<int\>_\. As a result, the return type of _std::vector<int\> &&_ is an rvalue reference to _vector<int\>_\.

The _std::move_ call results in an [xvalue](https://pvs-studio.com/en/blog/terms/6517/)\. This means that the resources of such an object can be reused\. If it's possible, move semantics \(not the copy semantics\) is applied for an xvalue expression\. For example, if the result of the _std::move _function is assigned to some _obj _object of the _type_ type, then the move assignment operator is called \(if it is defined for _type_\)\.

**Additional links:**

1. [The code analyzer is wrong\. Long live the analyzer\!](https://pvs-studio.com/en/blog/posts/cpp/0779/)