1. C++ / Говнокод #27107

    +2

    1. 1
    Class::Class(Pethu pethu) : pethu(std::move(pethu)) {

    std::move заебал. Просто взял, блядь, — и заебал!
    Чем это лучше передачи по ссылке?

    Запостил: guestinxo, 12 Ноября 2020

    Комментарии (26) RSS

    • Может быть тем, что Class может пережить своего вызываетля, и в таком случае ссылка превратится в тыкву?

      Но вообще разная семантика же совершенно.

      Мув: Я умираю, вот тебе мой петух, храни его, теперь он твой
      Ссылка: Могу одолжить тебе своего питуха на недельку
      Ответить
      • Нет, не так.

        Как сейчас:
        Вот тебе копия петуха, делай что хочешь. А я его муваю себе в конструкторе.

        А я хочу:
        Вот тебе отдалживаю петуха, копируй его себе сам, если хочешь.
        Ответить
        • В первом случае вызывающая сторона теряет петуха
          Ответить
          • Конечно же не теряет. При вызове функции он копируется, а в конструкторе мувается.
            Ответить
    • В таком виде у тебя pethu скопируется в параметр, а потом ты его переместишь в pethu-член класса.

      Обычно просто T (без const & или &&) принимают тогда, когда функция в любом случае будет копировать себе переданного петуха. То есть вместо
      void make_omelette(const Egg & egg)
      {
          auto egg_copy = Egg(egg);
          frying_pan.fry(egg_copy);
      }

      Пишут просто
      void make_omelette(Egg egg_copy)
      {
          frying_pan.fry(egg_copy);
      }
      Ответить
      • все, я понял: инью видимо спрашивает: какой смысл сначала копировать питуха, а потом сразу его мувать?

        если тебе не жалко уничтожить питуха на вызываемой стороне, то можно же передать ссылку, и мувнуть.
        Если тебе того петуха жалко, то просто копируй, и теки

        а так ты сначала его создаешь копированием, а потом сразу же отправляешь на компост
        Ответить
      • В твоём случае ты лишаешь копию коньстантности, поэтому тебе выгоднее сразу передать по значению.
        А я привела пример, где коньстантность сохраняется.

        В обоих случаях нахуй нужен «std::move» кроме как выебнуться - я не понимаю.
        Ответить
        • > нахуй нужен «std::move» кроме как выебнуться
          // вызываемая сторона (классический вореант)
          void foo(const Petuh& petuh) {
              m_petuh = petuh; // тут копируется
          }
          
          void foo(Petuh&& petuh) {
              m_petuh = std::move(petuh); // тут перемещается
          }
          
          // вызываемая сторона (универсальная ссылка)
          // не путать с обычной rvalue ссылкой в примере выше!
          template <typename T>
          void foo(T&& petuh) {
              m_petuh = std::forward(petuh);
          }
          
          // вызываемая сторона (передача по значению)
          void foo(Petuh petuh) {
              m_petuh = std::move(petuh);
          }
          
          // вызывающая сторона (одинаково для обоих вариантов)
          foo(petuh); // "я свою копию ещё поюзаю"
          foo(std::move(petuh)); // "мне моя копия больше не нужна"
          https://ideone.com/8qHHv3

          Теперь даже курицам всё понятно?
          Ответить
          • 3 способа сделать одно и то же )))
            Ответить
            • Угу. Из которых в одном джва раза копипастить, во втором городить шаблон на ровном месте, и только третий - няшный и пушистый.
              Ответить
          • Какой скилл )))

            std::forward<T> только.
            Ответить
            • > std::forward<T>

              Опечатался, я его не так часто юзаю. В реальном примере на ideone он есть.
              Ответить
          • > не путать с обычной rvalue ссылкой в примере выше!
            https://youtu.be/l_--ewb4YXg

            Предсказываю, кресты уже через несколько лет будут использоваться только там, где используется ассемблер - в микроконтроллерах и в задачах, где нужен пердолинг за лишний 1% производительности.

            Я уже говорил, что так концентрироваться на внешней шелухе (педерача значений, по значению, ссылке, питузу, консатному питуну на консатный петху) вместо решаемой задачи - это нездоровая питушня, связанная с тормозами компьютеров в прошлом веке. Сейчас дешевле, быстрее и надёжнее написать программу на более ссылочно прозрачном языке, чем C++.

            Широко использоваться будут простые динамические питухи вроде JS с уклоном на зомбирующих дуракозащищающих питухов вроде python - легко найти дешёвого программиста и написать небольшой-средний проект.
            Для средних-крупных проектов будет использоваться слабофункциональные языки - питушня с замыканиями и неизменяемыми данными или фреймворками для организации этого, ленивыми питухами. В отличие от тру функциональщины будет разрешена локальная нечисть в пределах функции или файла, но между модулями уже будут гулять только константные питухи.
            Ответить
            • Кстати, про const.

              const в C++ - формально приятная питушня, которая уменьшает количество проблем, но только в мечтах крестухов.

              Здесь всё то же самое, как и в ООП. Вроде всё логично и хорошо, но на практике - бюрократия в электронном виде, где работник общественной уборной не имеет право заменить клиенту рулон бумаги, и приходится ждать десять тактов до прихода оберпапирмейстера. А потом, когда заказчик попросит сделать двойные уборные для влюблённых, окажется, что всё надо переписывать или вносить в стройную иерархию классов говно.

              const тоже сначала долго прикидывается твоим бро, но ведёт себя как последнее говно, когда при изменении задачи тебе надо его куда-нибудь добавить или откуда-нибудь снять. Приходится просматривать всю диаграмму дейта флоу, следить за тем, чтобы в некоторых местах не копировали значение, чтобы не тратить память или получать по ссылке желаемые изменения, а в некоторых - наоборот копировали, чтобы не получать нежелательные изменения. Более того, если мы пишем чёрный ящик, который принимает const Pethu, то мы только гарантируем, что объект Pethu не сломает чёрный ящик. Но никто не гарантирует, что объект Pethu не сломает чёрный ящик. (Привет винительному питуху)
              Ответить
            • > предсказываю через несколько лет
              Как там в 2014? Небось, бакс по 30?
              Ответить
              • Я думал, в 2020 описанное либо не реализовано полностью, либо широко не распространено.
                Гроб C++ ещё не достаточно хорошо закопали в поле микроконтроллеров, язык жив и грязный императивный подход всё ещё вызывает миллионы баттхёртов по всему земному диску шару.
                Ответить
    • Ну это годный паттерн, на самом деле.

      С константной ссылкой клиент не может сказать "мне этот петух больше не нужен, забирай". И приходится ради него писать вторую версию функции с &&.

      Можно, конечно, через универсальную ссылку сделать, но она только в шаблонах работает и надувает бинарь.

      А с передачей по значению одна функция пригодна и для копирования и для мува. В итоге меньше копипасты и меньше говна в бинаре.
      Ответить
      • Почему клиенту больше не нужен то?? Передача по значению.
        Ответить
      • интересно, как клиент это скажет?
        Ответить
        • // держи копию петуха
          foo(petuh);
          
          // забирай своего петуха и ебись с ним
          foo(std::move(petuh));
          С const & у тебя работает только первый вызов. Для второго пришлось бы писать отдельную функцию, которая принимает && или шаблон с универсальной ссылкой. А здесь одной реализацией убиваешь двух мартышек.
          Ответить
          • я запутался

            Это говорит ВЫЗЫВАЮЩАЯ сторона? Тогда нахуя ВЫЗВАЕМЫЙ код делает Mov?
            Ответить
            • > Это говорит ВЫЗЫВАЮЩАЯ сторона

              Да, примеры приведены с вызывающей стороны. И они в общем-то ничем не отличаются от классических const & и &&.

              > нахуя ВЫЗВАЕМЫЙ код делает Mov

              А нахуя вызываемой стороне копировать аргумент, который всё равно сдохнет в конце вызова? Вполне логично, что вызываемый код его мувает.
              Ответить
              • Но ведь если написано ``Class(Pethu pethu)``, то питух всё равно скопируется, нет?.
                Просто если вызывающая сторона сделает Move, то она разрушит своего питуха.

                В случае же ссылки мы могли бы вообще ничего никуда не копировать, если мы знаем, что петух будет жить дольше вызывемой стороны..

                Кстати, а можно сделать два конструктора: один получает питуха по ссылке, другой по значению, и вызывающая сторона выбирает:
                * скопировать
                * мувнуть
                * передать ссылку

                Или в С++ вызывающая сторона такие вещи не решает, если только там не указатель?
                Ответить
            • Чтобы дать вызывающей стороне возможность избавиться от петуха. Она может пользоваться этой возможностью, а может и нет.

              Борманд умный, я за Борманда!
              Ответить
          • Спасибо. Теперь поняла.
            Ответить

    Добавить комментарий