Информация об изменениях

Сообщение Re[6]: Есть ли жизнь после перемещения? от 20.11.2018 19:06

Изменено 20.11.2018 19:11 rg45

Re[6]: Есть ли жизнь после перемещения?
Здравствуйте, Erop, Вы писали:

E>Раз очень много чего, то, наверное, не трудно привести три-пять примеров? А то я не уверен, что мы одинаково понимаем слово "упростилось"...


Например, можно стало смелее оперировать с коллекциями тяжелых объектов, не боясь переаллокаций, ушла необходимость в лишней косвенности. Многие классы, для которых трудно и нецелесообразно пледоставлять копирование вполне поддаются перемещению, зачастую очень простому и дешевому. Проще стало возвращать значения из фунцкций — если не отработает RVO/NRVO, по каким-то причинам, то move точно не подведет. Не нужно ломать голову, какой выбрать умный указатель, чтобы вернуть из функции некопируемый объект. Уменшьшилась потребность в аутпут параметрах, что в целом положительно отразилось на общей структуре кода. Например, запросто можно позволить себе такое вот простейшую и в тоже время очень юзабельную реализацию дерева. Причем, деревья эти могут иметь какую угодно сложность, а все манипуляции с ними будут не с ложнее, чем с парой простых указаделей. И это гарантировано, потому, что в данном случае копирование запрещено, разрешено только перемещение:

template <typename T>
class Tree : public std::vector<Tree<T>>
{
public:

  template <typename...U>
  Tree(U&&...u) : m(std::forward<U>(u)...) {}
  
  Tree() = default;
  Tree(Tree&&) = default;
  Tree& operator = (Tree&&) = default;

  T& operator* () { return m; }
  const T& operator* () const { return m; }

private:
  T m;
};


R>>Кому надо-то? Если ты будешь писать, как писал на C++03, никакой мув семантики ты даже не заметишь. Добавились новые возможности, но добавились ненавязчиво — хочешь используй, хочешь нет.


E>Ужасная история по мотивам охоты за багой.

E>...
E>Ну и в сложных конструкциях всяких таких хитрых эффектов скока хочешь приключается.

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

E>Если мы RAII объект мувим, то на старом месте остаётся существующий объект, которому не соответствует никакой ресурс.


То на старом месте остается указатель или хэндл ресурса просто обнуляется, как обнуляется указатель в смарт-поинтере. В более сложном случае мув семантика просто не поддерживается и заменяется на копирование. Только существование таких более сложных случаев вовсе не отменяет эффективности мув в семаники во всех других случаях.

E>А вот представь себе, что были бы смарт-ссылки? У смартпоинтеров есть "нулевое" состояние, в отличии от чистого RAII


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

E>Речь идёт о возврате из функций? Чаще всего с этим справлялось RVO…


Ага, чаще всего справлялось. Только разработчики зачастую говорили/думали: "да ну его нафиг, этот РВО, х.з. отработает или нет, заведу-ка я аутпут переменную..."
Re[6]: Есть ли жизнь после перемещения?
Здравствуйте, Erop, Вы писали:

E>Раз очень много чего, то, наверное, не трудно привести три-пять примеров? А то я не уверен, что мы одинаково понимаем слово "упростилось"...


Например, можно стало смелее оперировать с коллекциями тяжелых объектов, не боясь переаллокаций, ушла необходимость в лишней косвенности. Многие классы, для которых трудно и нецелесообразно пледоставлять копирование вполне поддаются перемещению, зачастую очень простому и дешевому. Проще стало возвращать значения из фунцкций — если не отработает RVO/NRVO, по каким-то причинам, то move точно не подведет. Не нужно ломать голову, какой выбрать умный указатель, чтобы вернуть из функции некопируемый объект. Уменшьшилась потребность в аутпут параметрах, что в целом положительно отразилось на общей структуре кода. Например, запросто можно позволить себе такое вот простейшую и в тоже время очень юзабельную реализацию дерева. Причем, деревья эти могут иметь какую угодно сложность, а все манипуляции с ними будут не тяжелее, чем с парой простых указаделей. И это гарантировано, потому, что в данном случае копирование запрещено, разрешено только перемещение:

template <typename T>
class Tree : public std::vector<Tree<T>>
{
public:

  template <typename...U>
  Tree(U&&...u) : m(std::forward<U>(u)...) {}
  
  Tree() = default;
  Tree(Tree&&) = default;
  Tree& operator = (Tree&&) = default;

  T& operator* () { return m; }
  const T& operator* () const { return m; }

private:
  T m;
};


R>>Кому надо-то? Если ты будешь писать, как писал на C++03, никакой мув семантики ты даже не заметишь. Добавились новые возможности, но добавились ненавязчиво — хочешь используй, хочешь нет.


E>Ужасная история по мотивам охоты за багой.

E>...
E>Ну и в сложных конструкциях всяких таких хитрых эффектов скока хочешь приключается.

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

E>Если мы RAII объект мувим, то на старом месте остаётся существующий объект, которому не соответствует никакой ресурс.


То на старом месте остается указатель или хэндл ресурса просто обнуляется, как обнуляется указатель в смарт-поинтере. В более сложном случае мув семантика просто не поддерживается и заменяется на копирование. Только существование таких более сложных случаев вовсе не отменяет эффективности мув в семаники во всех других случаях.

E>А вот представь себе, что были бы смарт-ссылки? У смартпоинтеров есть "нулевое" состояние, в отличии от чистого RAII


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

E>Речь идёт о возврате из функций? Чаще всего с этим справлялось RVO…


Ага, чаще всего справлялось. Только разработчики зачастую говорили/думали: "да ну его нафиг, этот РВО, х.з. отработает или нет, заведу-ка я аутпут переменную..."