Все про std::forward | передача по значению - это ОК | Семантика перемещения

Поделиться
HTML-код
  • Опубликовано: 17 янв 2025

Комментарии • 20

  • @PolevoysProgramming
    @PolevoysProgramming  7 дней назад +1

    00:09 - *идельную передачу (Perfect forwarding)

  • @TurboGamasek228
    @TurboGamasek228 3 дня назад

    супер полезный канал

  • @artefek7300
    @artefek7300 7 дней назад

    Видео было очень полезным, спасибо!

  • @toxic_champ
    @toxic_champ 7 дней назад +2

    после этого видоса я задаюсь вопросом, а так ли я хочу изучать плюсы...

    • @kenol8779
      @kenol8779 6 дней назад

      По факту здесь ничего сложного нет, просто есть небольшая путаница с lvalue и rvalue)) Даже если не углубляться в это в начале обучения, со временем все равно поймешь.

  • @Desotterro
    @Desotterro 7 дней назад

    Астрологи объявили год годноты, количество крутого контента увеличолсь.

  • @bigrussianbossshow9420
    @bigrussianbossshow9420 7 дней назад

    27:56 c rvalue будет 0 копирований и 1 перемещение, разве нет?

    • @PolevoysProgramming
      @PolevoysProgramming  7 дней назад +1

      Если мы сразу передаем r-value, то, конечно же, будет просто одно перемещение, я тут имел ввиду, если мы будет передавать l-value через move:
      std::string str = "some long string";
      ....
      add(std::move(str));

    • @denisgluk431
      @denisgluk431 3 дня назад

      @@PolevoysProgramming как это работает? так же, как return сделали? первый раз про такую фишку слышу

    • @PolevoysProgramming
      @PolevoysProgramming  3 дня назад

      @@denisgluk431 Нет, не как return, тут все проще
      Смотри, у тебя есть какая-то функция, которая принимает какой-то параметр, и ты знаешь, что этот параметр в этой функции точно будет скопирован. Я привел пример с добавлением в вектор, но давай другой пример рассмотрим, может он будет проще для понимания:
      пусть у нас есть класс Person, у него есть поле имя: (тут важно, что std::string имеет конструктор перемещения)
      class Person
      {
      std::string name;
      // передаем по l-ссылке - тут нет копирования
      Person(const std::string &name)
      {
      // А тут копирование
      this->name = name;
      }
      };
      Чтобы ты не передал в конструктор - у тебя всегда будет одно копирование. А раз ты неизбежно всегда создаешь копию объекта, то можно делать копию не в момент присваивания полю класса, а в момент передачи в параметр:
      class Person
      {
      std::string name;
      // Теперь тут создается копия
      Person(std::string name)
      {
      // А тут копию всегда перемещаем, это же копия, она исходный объект не поменяет
      this->name = std::move(name);
      }
      };
      В первом случае - у нас было только одно копирование, во втором случае - одно копирование + одно перемещение. НО! теперь при передачи r-value, например так:
      std::string someString = ".....";
      Person p(std::move(someString));
      копия будет создана путем конструктора перемещения, да + еще одно перемещение в момент присваивания полю:
      // случай с r-value
      Person(std::string name) // name = std::move(someString) (раз перемещение)
      {
      // А тут копию всегда перемещаем
      this->name = std::move(name); // (два перемещение)
      }
      И того, у нас два перемещения.
      Поэтому если твой объект умеет перемещаться, да еще его перемещение настолько дешевое (например просто переставляются указатели) - то ты можешь сказать, окей, хрен с ним, я пожертвую одним лишним перемещением (то есть я готов на то, что всегда будет хотя бы одно перемещение), зато мне не надо будет создавать две перегрузки для обработки случая для r-value.
      Вот, в целом, никакой магии. Надеюсь стало более понятно
      PS.
      1. Можешь посмотреть объяснение от Ильи Мещерена (парень успел поработать в Гугле и Яндексе, сейчас параллельно преподает в МФТИ) - в одной из лекций по семантике перемещения (надо искать, так не помню, какая именно)
      2. У Скотта Мейерса в книге "Эффективный и современный с++. 42 рекомендации..." глава 8.1 полностью посвящена этой теме

  • @Mercury13kiev
    @Mercury13kiev 7 дней назад

    Ответ на последнее - нужно было в первых редакциях Си11. Потом прикрыли.

  • @Ma_X64
    @Ma_X64 6 дней назад

    И в очередной раз разработчики C++ блестяще решили проблему, которую сами же и создали.)))

  • @Selfrock_Vladimir
    @Selfrock_Vladimir 7 дней назад

    передал по ссылке...

  • @portusdelphini
    @portusdelphini 7 дней назад

    Все это хорошо, но ничего не понятно, как это происходит на уровне ассемблера, на уровне регистров, стека

    • @artembystrov1113
      @artembystrov1113 7 дней назад

      Здесь вообще все на поверхности. У тебя указатель на область памяти при std::move просто переносится а при копировании новый выделяется. Если говорить про стек тоже самое будет те же указатели и доп информация структур проплоцирлванных

    • @NXN-QUXT
      @NXN-QUXT 7 дней назад +1

      Как компилятор захочет, так на ассемблере и будет реализовано

  • @ИнякинАлександр
    @ИнякинАлександр 7 дней назад +2

    Сплошные костыли вместо вывода типов здорового человека.

    • @Ma_X64
      @Ma_X64 6 дней назад +1

      🤝

  • @DART2WADER
    @DART2WADER 6 дней назад

    Лайк за креатор, а то эмаксвимовские консольные сектанты надоели.