1.5Kпросмотров
39.8%от подписчиков
17 января 2026 г.
questionScore: 1.6K
📦 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