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

Функция _std::forward_, наряду с [_std::move_](https://pvs-studio.ru/ru/blog/terms/6518/), предназначена для реализации [семантики перемещения](https://pvs-studio.ru/ru/blog/terms/6514/) в C\+\+\. Она принимает [forwarding\-ссылку](https://pvs-studio.ru/ru/blog/terms/6517/), по шаблонному параметру _T_ определяет, передана ей lvalue\-ссылка или rvalue\-ссылка и возвращает ссылку соответствующего типа\. Назначение функции _std::forward_ – это реализация механизма идеальной передачи \(perfect forwarding\)\. Этот механизм подразумевает, что объекты, переданные в функцию в виде lvalue\-выражений, должны копироваться, а объекты, переданные в функцию в виде rvalue\-выражений, должны перемещаться\.

Дело в том, что если присвоить rvalue\-ссылку некоторой переменной _ref_, то _ref_ будет именованной сущностью, поэтому его категория – lvalue, несмотря на то что тип переменной _ref_ – rvalue\-ссылка\. Поэтому для _ref_ будет использоваться семантика копирования, а не перемещения\.

Функция _std::forward_ решает эту проблему\. Рассмотрим следующий пример: 

```cpp
template <typename T>
void foo(T &&arg)
{
  std::vector<int> var = arg;
  ....
}

std::vector<int> vect(1'000'000, 1);
foo(std::move(vect));
```

В коде происходит следующее:

* Вызывается функция _std::move_, которая возвращает rvalue\-ссылку на _vect_\.
* Эта ссылка передается по forwarding\-ссылке в экземпляр функции _foo_ в качестве аргумента _arg_\. _arg_ – это lvalue\-объект, имеющий тип rvalue\-ссылки\.
* Происходит инициализация переменной _var_, которая вызывает конструктор копирования\. _vector vect_ копируется поэлементно в переменную _var_\.

А теперь воспользуемся _std::forward_:

```cpp
template <typename T>
void foo(T &&arg)
{
  std::vector<int> var = std::forward<T>(arg);
  ....
}

std::vector<int> vect(1'000'000, 1);
foo(std::move(vect));
```

Здесь происходит следующее:

* Вызывается функция _std::move_, которая возвращает rvalue reference на _vect_\.
* Эта ссылка передается по forwarding\-ссылке в экземпляр функции _foo_ в качестве аргумента _arg_\. _arg_ – это lvalue\-объект, имеющий тип rvalue\-ссылки\.
* Происходит вызов функции _std::forward_, которая возвращает [xvalue\-объект](https://pvs-studio.ru/ru/blog/terms/6517/) с типом rvalue\-ссылка\.
* Происходит инициализация переменной _var_, которая вызывает оператор перемещения\. _vector vect_ перемещается в переменную _var_\.