TGViewer
C++ geek C++ geek @cpp_geek · 3.53K subscribers
Post #398 1.61K
📦 std::move vs std::forward: Когда и зачем?

На собеседованиях часто спрашивают про rvalue-ссылки, но в реальном коде мы постоянно путаемся: когда делать move, а когда forward?

Давайте разберем на жизненных примерах.

1. std::move - "Это мое, но забирай!" 🚚

std::move - это безусловное приведение к rvalue. Вы говорите компилятору: "Мне этот объект больше не нужен. Можешь выпотрошить его и забрать данные, не копируя их".

Сценарий 1: Передача владения (unique_ptr)
Это классика. std::unique_ptr нельзя скопировать, его можно только переместить.


auto ptr = std::make_unique<BigData>();

// process(ptr); // ❌ Ошибка компиляции! Копирование запрещено.
process(std::move(ptr)); // ✅ ОК. Владение передано, ptr теперь пуст.



Сценарий 2: Оптимизация тяжелых объектов
У вас есть локальный вектор, который вы хотите сохранить в поле класса. Зачем его копировать?


void SetData(std::vector<int> newData) {
// Мы крадем буфер памяти у newData.
// Копирования элементов НЕ происходит.
this->data_ = std::move(newData);
}




2. std::forward - "Я просто посредник" 📮

std::forward используется почти исключительно в шаблонах. Его цель - Perfect Forwarding (Идеальная передача).

Представьте, что вы пишете функцию-обертку (wrapper). Она принимает аргумент и должна передать его дальше другой функции.

⚫️Если ей передали временный объект (rvalue) - она должна передать его как rvalue (чтобы сработал move).
⚫️Если передали обычную переменную (lvalue) - она должна передать как lvalue (копия).

std::move здесь всё испортит (он всё превратит в rvalue). Тут нужен std::forward.

Сценарий: Фабрики и Обертки


template <typename T>
void LogAndAdd(std::vector<T>& vec, T&& item) {
std::cout << "Adding item...";

// forward сохранит категорию значения item.
// Если item был временным — сработает push_back(T&&) (перемещение).
// Если item был переменной — сработает push_back(const T&) (копия).
vec.push_back(std::forward<T>(item));
}




⚡️ Шпаргалка

1. std::move используем, когда мы знаем, что объект нам больше не нужен, и мы хотим отдать его ресурсы (обычный код).
2. std::forward используем, когда мы пишем шаблон, который принимает "универсальную ссылку" (T&&), и нам нужно пробросить аргумент дальше "как есть" (библиотечный код).

#cpp #cpp11 #movesemantics #coding #interview #tips

➡️ @cpp_geek
  • 👍 8
  • ❤ 3
More from @cpp_geek
  1. Sep 24, 2026🎥 Вебинар по C++: Паттерн многопоточного программирования «Producer-Consumer» Когда неско…
  2. Sep 24, 2026Execution policy для параллельных алгоритмов Execution policy в C++ — это новшество, введе…
  3. Sep 17, 2026В чем разница между git fetch и git pull? Разница между этими командами заключается в том,…
  4. Sep 15, 2026std::tie std::tie — это функция, которая создает кортеж ссылок на lvalue из своих аргумент…
  5. Sep 11, 2026move constructor Move-конструктор — это специальный конструктор, который позволяет эффекти…
  6. Sep 9, 2026Move-only объекты и почему std::unique_ptr нельзя копировать Многие удивляются, когда комп…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →