﻿# Функция std::move

Функция _std::move_ предназначена для реализации [семантики перемещения](https://pvs-studio.ru/ru/blog/terms/6514/)\. Она принимает [forwarding\-ссылку](https://pvs-studio.ru/ru/blog/terms/6517/) на объект и возвращает rvalue\-ссылку на этот объект\. Одна из возможных реализаций _std::move_ выглядит так:

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

В функцию _std::move_ может быть передана как lvalue\-ссылка, так и rvalue\-ссылка, а результатом должна являться rvalue\-ссылка\. Поэтому для обозначения возвращаемого типа сначала используем трейт _std::remove\_reference\_t_, который упрощает шаблонный тип _T_ до обычного нессылочного типа, а затем явно добавляем '&&'\. Рассмотрим следующий фрагмент кода:

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

Вот что здесь происходит:

* Инстанцируется экземпляр функции _std::move_ с шаблонным типом _T \= std::vector<int\> &_\.
* Этот экземпляр принимает аргумент типа _std::vector<int\> &_\. При попытке сформировать аргумент в виде rvalue\-ссылки на _std::vector<int\> &_ компилятор воспользуется правилом сжатия ссылок, и результирующий тип аргумента эквивалентен _std::vector<int\> &_\. Это lvalue\-ссылка на _vector<int\>_\.
* Трейт _std::remove\_reference\_t_ возвращает упрощенный до нессылочного типа тип _std::vector<int\>_, к которому добавляется '&&'\. В итоге возвращаемый тип _std::vector<int\> &&_ – это rvalue\-ссылка на _vector<int\>_\.

Теперь рассмотрим случай, когда в _std::move_ передается rvalue\-ссылка:

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

В этом случае происходит следующее:

* Инстанцируется экземпляр функции _move_ с шаблонным типом _T \= std::vector<int\>_\.
* Этот экземпляр принимает аргумент типа _std::vector<int\> &&_\. Это rvalue\-ссылка на _vector<int\>_\.
* Трейт _std::remove\_reference\_t_ возвращает упрощенный до нессылочного типа тип _std::vector<int\>_, к которому добавляется '&&'\. Итого возвращаемый тип типа _std::vector<int\>&&_ – это rvalue\-ссылка на _vector<int\>_\.

Результатом вызова _std::move_ будет объект с категорией [xvalue](https://pvs-studio.ru/ru/blog/terms/6517/)\. Это означает, что ресурсы такого объекта могут быть переиспользованы\. Для xvalue\-выражения будет применяться семантика перемещения, а не семантика копирования, если это возможно\. Например, если результат вызова функции _std::move_ присваивается некоторому объекту _obj_ типа _type_, то будет вызван оператор перемещающего присваивания \(если для _type_ такой определен\)\.

**Дополнительные ссылки:**

1. [Анализатор кода не прав, да здравствует анализатор](https://pvs-studio.ru/ru/blog/posts/cpp/0779/)\.