Re[4]: Есть ли жизнь после перемещения?
От: ViTech  
Дата: 20.11.18 15:30
Оценка:
Здравствуйте, andyp, Вы писали:

A> Т.е. он уже начал подумывать как различать мишку, коробку и мишку в коробке. Имхо, в стране розовых пони, если ты смувил из объекта, его тип должен автоматически переключаться на Вох<T> и не давать тебе с таким объектом шалить. Сама концепция такой коробки тоже достаточно полезна имхо.


Если считать обращение к перемещённому объекту ошибкой, то нужны инструменты, которые могут это отслеживать на этапе компиляции. Надеюсь доживём до Lifetime profile.
Пока сам не сделаешь...
Re[5]: Есть ли жизнь после перемещения?
От: andyp  
Дата: 20.11.18 16:10
Оценка:
Здравствуйте, ViTech, Вы писали:

VT>Если считать обращение к перемещённому объекту ошибкой, то нужны инструменты, которые могут это отслеживать на этапе компиляции. Надеюсь доживём до Lifetime profile.


К сожалению статический анализ имхо не закроет все темы:

void test(bool condition)
{
    A a,b;
    if(condition)
    {
        b = std::move(a);    
    }    
    //а пусто или полно? В статике не узнать.
    //сейчас деструктор будет вызван вне зависимости от.
}
Re[3]: Есть ли жизнь после перемещения?
От: B0FEE664  
Дата: 20.11.18 16:21
Оценка: 16 (1)
Здравствуйте, rg45, Вы писали:

R>А как насчет операции присваивания (или reset какой-нибудь)? Я не вижу причин, фигурально выражаясь, запрещать возможность вдохнуть в объект новую жизнь.


На практике (кроме как внутри swap), никакого присваивания к перемещённому объекту у меня желания сделать не возникало. Допускаю, что возможно это связано с теми задачами, что я решаю. Я почти не пишу шаблонного кода последние 6 месяцев. А вообще, наверное можно подходить так: объект — это интерфейс + данные. Перемещение уносит данные из объекта. Объект без данных — это просто интерфейс. Соответственно, чтобы продолжать работу с объектом, его надо наполнить данными. Как-то так.
И каждый день — без права на ошибку...
Re[4]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 16:25
Оценка:
Здравствуйте, B0FEE664, Вы писали:


R>>А как насчет операции присваивания (или reset какой-нибудь)? Я не вижу причин, фигурально выражаясь, запрещать возможность вдохнуть в объект новую жизнь.


BFE>На практике (кроме как внутри swap), никакого присваивания к перемещённому объекту у меня желания сделать не возникало. Допускаю, что возможно это связано с теми задачами, что я решаю. Я почти не пишу шаблонного кода последние 6 месяцев. А вообще, наверное можно подходить так: объект — это интерфейс + данные. Перемещение уносит данные из объекта. Объект без данных — это просто интерфейс. Соответственно, чтобы продолжать работу с объектом, его надо наполнить данными. Как-то так.


Ну то есть, скорее "да", чем "нет", можно присваивать, правильно я тебя понял?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 16:37
Оценка:
Здравствуйте, rg45, Вы писали:

E>>1) IMHO, вопрос хороший. С ещё одной стороны показывает насколько убога концепция мув-семантики.

R>Не могу согласиться, при всем уважении. ИМХО, это скорее показывает какой-то неудачный опыт применения.
А какой код упростился? Стал удобнее, поддерживаемее или ещё в чём-то лучше?
То, что теперь надо у всех встречных поперечных классов ещё один конструктор и оператор присваивания писать, вряд ли можно считать за упрощение кода?
В целом быстродействие/память только в редких бутылочных горлышках критичны, а мов-семантика расползается по всему коду...

При этом она противоречит чистому RAII, требует существования "пустого" состояния объектов, не может нормально работать с большими объектами размещёнными на стеке, в отличии от RVO и т. д...


E>>2) Опять же, IMHO, нужно идти от того, какие сценарии, с использованием оставшегося после перемещения объекта, мы считаем валидными.


R>Так это я об этом спрашиваю, вообще-то


Ну я знаю только один такой сценарий -- вставку/удаление элемента в массив.
И на мой взгляд ради этой операции мутить семантику перемещения в языке -- это оверкил был...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Есть ли жизнь после перемещения?
От: B0FEE664  
Дата: 20.11.18 16:38
Оценка:
Здравствуйте, rg45, Вы писали:

R>>>А как насчет операции присваивания (или reset какой-нибудь)? Я не вижу причин, фигурально выражаясь, запрещать возможность вдохнуть в объект новую жизнь.

R>Ну то есть, скорее "да", чем "нет", можно присваивать, правильно я тебя понял?

Скорее "да", чем "нет", но прошу учесть, что это мнение, а не знание.
И каждый день — без права на ошибку...
Re[4]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 17:43
Оценка: +2
Здравствуйте, Erop, Вы писали:

E>А какой код упростился? Стал удобнее, поддерживаемее или ещё в чём-то лучше?


Очень много чего упростилось. Перечислять не стану, примеров просто бездна.

E>То, что теперь надо у всех встречных поперечных классов ещё один конструктор и оператор присваивания писать, вряд ли можно считать за упрощение кода?


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

E>В целом быстродействие/память только в редких бутылочных горлышках критичны, а мов-семантика расползается по всему коду...


Что значит, она расползается? Используй только там, где она реально приносит пользу, а не где попало, и ничего никуда расползаться не будет.

E>При этом она противоречит чистому RAII, требует существования "пустого" состояния объектов, не может нормально работать с большими объектами размещёнными на стеке, в отличии от RVO и т. д...


Как это RAII может конфликтовать с move семантикой, интересно? Ну взять классику жанра — смартпоинтеры. В них во все сейчас подобавляли перемещающие конструкторы и операторы присваивания. При этом места их использования никак менять не пришлось, просто код стал более эффективным, порой чувствительно. В тех местах, где раньше происходило копирование смартпоинтера, выполнялась интерлокед операция и сбрасывался кэш процессора, сейчас происодит move, который сводится к переброско одного несчастного указателя — все!
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 17:56
Оценка:
Здравствуйте, rg45, Вы писали:

R>Очень много чего упростилось. Перечислять не стану, примеров просто бездна.

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

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


Ужасная история по мотивам охоты за багой.
1) У нас есть класс -- авторегистрилка в уведомлялке.
Если нам надоть на что-то подписаться, мы из этой штуки выводимся, и она сама подписывается/отписывется все дела.
2) Что бы можно было юзать RVO, эта авторегистрика умеет конструктор копии, который при RVO всё не зовут, но если позовут, вдруг, ну будет два подписывания/отписывания вместо одного.
3) Мы разводим три вагона каких-то классов, у которых куча авторегистрилок в базах, что бы куда-то регаться/разрегиваться и всё такое.

// тут мы переходим от C++03 к более совершенным версиям


4) Авторигестрилке приписывают move-конструктор, который заменяет подписчика в списке источника уведомлений, вместо того, что бы массив туда-сюда двигать

5) В каких-то случаях случаются странные эффекты при вызовах автосгенерированных move-конструкторов...

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

R>Как это RAII может конфликтовать с move семантикой, интересно?

Классический RAII это объект есть -- ресурс захвачен, объект разрушен -- ресурс освобождён.
Если мы RAII объект мувим, то на старом месте остаётся существующий объект, которому не соответствует никакой ресурс.

R>Ну взять классику жанра — смартпоинтеры. В них во все сейчас подобавляли перемещающие конструкторы и операторы присваивания. При этом места их использования никак менять не пришлось, просто код стал более эффективным, порой чувствительно.


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

R>В тех местах, где раньше происходило копирование смартпоинтера, выполнялась интерлокед операция и сбрасывался кэш процессора, сейчас происодит move, который сводится к переброско одного несчастного указателя — все!

Речь идёт о возврате из функций? Чаще всего с этим справлялось RVO…
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 18:04
Оценка:
Здравствуйте, rg45, Вы писали:

R>Я, в общем-то придеживаюсь близких взлядов, но формулирую их чуть по-другому: "не следует применять операцию move к объекту, который предполагается еще использовать". Вроде бы, одно и то же, но звучит более логично, имхо.



А удаление объекта из середины массива, путём цепочки перемещений, ты валидным не считаешь разве?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 18:08
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Скорее "да", чем "нет", но прошу учесть, что это мнение, а не знание.



Разве вставка не в конец в std::vector сейчас не через цепочку move-конструкторов/присваиваний работает?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 18:35
Оценка: +1
Здравствуйте, Erop, Вы писали:

R>>Я, в общем-то придеживаюсь близких взлядов, но формулирую их чуть по-другому: "не следует применять операцию move к объекту, который предполагается еще использовать". Вроде бы, одно и то же, но звучит более логично, имхо.


E>А удаление объекта из середины массива, путём цепочки перемещений, ты валидным не считаешь разве?


Считаю. Мы это обсудили уже, ниже по ветке.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 19:06
Оценка: +2
Здравствуйте, Erop, Вы писали:

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


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

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

  template <typename...U>
  explicit Tree(U&&...u) : m(std::forward<U>(u)...) {}
  
  // Movable but non-copyable
  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…


Ага, чаще всего справлялось. Только разработчики зачастую говорили/думали: "да ну его нафиг, этот РВО, х.з. отработает или нет, заведу-ка я аутпут параметр..."
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.11.2018 19:44 rg45 . Предыдущая версия . Еще …
Отредактировано 20.11.2018 19:43 rg45 . Предыдущая версия .
Отредактировано 20.11.2018 19:11 rg45 . Предыдущая версия .
Отредактировано 20.11.2018 19:07 rg45 . Предыдущая версия .
Re[7]: Есть ли жизнь после перемещения?
От: lpd Черногория  
Дата: 20.11.18 20:01
Оценка:
Здравствуйте, rg45, Вы писали:

R>Например, можно стало смелее оперировать с коллекциями тяжелых объектов, не боясь переаллокаций, ушла необходимость в лишней косвенности.

Прощай лишняя косвенность, здравствуй rvalue reference.

R> Многие классы, для которых трудно и нецелесообразно пледоставлять копирование вполне поддаются перемещению, зачастую очень простому и дешевому.

Сложно придумать пример класса, для которого копирование реализовать сложнее, чем перемещение. И зачем экономить на копировании большинства классов?

R> Проще стало возвращать значения из фунцкций — если не отработает RVO/NRVO, по каким-то причинам, то move точно не подведет.

Я понял, у тебя фобия лишней косвенности. Могу напомнить: под капотом у rvalue reference все то же самое.

R> Не нужно ломать голову, какой выбрать умный указатель, чтобы вернуть из функции некопируемый объект.

Допустим(это я не понял, особенно зачем ты часто подобными проблемами мучаешься).

R> Уменшьшилась потребность в аутпут параметрах, что в целом положительно отразилось на общей структуре кода.

Я все таки на всякий случай спрошу: надеюсь, ты не всем вподряд типам добавляешь move-конструкторы?
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Re[8]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 20:11
Оценка:
Здравствуйте, lpd, Вы писали:

lpd>Прощай лишняя косвенность, здравствуй rvalue reference.


Как пример упрощения. Без косвенности проще, чем с ковенностью.

lpd>Сложно придумать пример класса, для которого копирование реализовать сложнее, чем перемещение. И зачем экономить на копировании большинства классов?


Запросто, смотри

class PhysicalWorld
{
public:

  PhysicalWorld();
  PhysicalWorld(PhysicalWorld&&) = default;
  PhysicalWorld& operator = (PhysicalWorld&&) = default;

  // Задолбишься пыль глотать.
  // Да и нафиг не нужно никому.
  // Поэтому non-copyable
  PhysicalWorld(const PhysicalWorld&) = delete;
  PhysicalWorld& operator = (const PhysicalWorld&) = delete;

private:
  class Impl;
  std::inique_ptr<Impl> m {};
};


R>> Проще стало возвращать значения из фунцкций — если не отработает RVO/NRVO, по каким-то причинам, то move точно не подведет.

lpd>Я понял, у тебя фобия лишней косвенности. Могу напомнить: под капотом у rvalue reference все то же самое.

Где ты тут что про косвенность нашел

lpd>Допустим(это я не понял, особенно зачем ты часто подобными проблемами мучаешься).


Ну потому что я иногда не только палочкой окаменелые какашки ковыряю, как некоторые.

lpd>Я все таки на всякий случай спрошу: надеюсь, ты не всем вподряд типам добавляешь move-конструкторы?


Нет, конечно. Зачем же мне у компилятора отбирать его работу. А там где добавляю, то чаще всего как default, как в примере выше. Странное у тебя представленние о поддержке мув-семантики, надо сказать.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.11.2018 20:16 rg45 . Предыдущая версия . Еще …
Отредактировано 20.11.2018 20:12 rg45 . Предыдущая версия .
Re[9]: Есть ли жизнь после перемещения?
От: lpd Черногория  
Дата: 20.11.18 20:21
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, lpd, Вы писали:


lpd>>Я все таки на всякий случай спрошу: надеюсь, ты не всем вподряд типам добавляешь move-конструкторы?


R>Нет, конечно. Зачем же мне у компилятора отбирать его работу. А там где добавляю, то чаще всего как default, как в примере выше. Странное у тебя представленние о поддержке мув-семантики, надо сказать.


Имею ввиду: надеюсь, не всегда используешь move-семантику и rvalue-reference, где возможно? Ради каких крох производительности ты на это заморачиваешься?
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Re[10]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 20.11.18 20:25
Оценка:
Здравствуйте, lpd, Вы писали:

R>>Нет, конечно. Зачем же мне у компилятора отбирать его работу. А там где добавляю, то чаще всего как default, как в примере выше. Странное у тебя представленние о поддержке мув-семантики, надо сказать.


lpd>Имею ввиду: надеюсь, не всегда используешь move-семантику и rvalue-reference, где возможно? Ради каких крох производительности ты на это заморачиваешься?


Что значит, "я не использую", когда зачастую мув семантика доступна по умолчанию и нужно сделать дополнительные телодвижения для того, чтобы ее запретить? Я разверну тебе твой вопрос: ради чего ты предлагаешь заморачиваться, чтобы побороть доступную по умолчанию мув семантику?

Как ты не поймешь, что "поддержка мув семантике" это совсем не означает добление по клавишам. Чаше всего этот процесс происходит в голове — это просто осмысленное отношение к коду, который выходит из под твоих пальцев.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.11.2018 20:28 rg45 . Предыдущая версия .
Re[11]: Есть ли жизнь после перемещения?
От: lpd Черногория  
Дата: 20.11.18 20:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, lpd, Вы писали:


lpd>>Имею ввиду: надеюсь, не всегда используешь move-семантику и rvalue-reference, где возможно? Ради каких крох производительности ты на это заморачиваешься?


R>Что значит, "я не использую", когда зачастую мув семантика доступна по умолчанию и нужно сделать дополнительные телодвижения для того, чтобы ее запретить? Я разверну тебе твой вопрос: ради чего ты предлагаешь заморачиваться, чтобы побороть доступную по умолчанию мув семантику?


Я не особенно часто ее использовал, и если она доступна по умолчанию, это хорошо, хотя я и сильно сомневаюсь, что она по умолчанию доступна столь часто.
Я предлагаю не использовать move-семантику почти никогда, ради того, чтобы просто присваивать переменные, как это всегда делалось, и не возиться с запутанными правилами преобразования rvalue-reference. Не замусоривать код всеми этими std::move, которые нужно держать в голове, и которые абсолютно ничего не дают, кроме десятых долей процента быстродействия программы, которыми можно пренебречь.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Re[7]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 20:40
Оценка:
Здравствуйте, rg45, Вы писали:

R>Например, можно стало смелее оперировать с коллекциями тяжелых объектов, не боясь переаллокаций, ушла необходимость в лишней косвенности. Многие классы, для которых трудно и нецелесообразно пледоставлять копирование вполне поддаются перемещению, зачастую очень простому и дешевому.


Наверное я неточно выразился. Я не то, что бы против решения таких проблем, я просто считаю, что такое решение, какое выбрали, негодным.

Смотри, одна история — это дефект дизайна std::vector, так как он не умеет move-семантику на уровне библиотеки, а не языка.
Ну да он много чего не умел в С++98, впрочем и сейчас не до конца выпрямился.
В любом случае, были более или менее простые решения, вроде стандартизации шаблонной функции вроде
template<typename T>
void move_vector_item( void* dst, T* src )
{
    assert( src != 0 && dst != 0 && dst != src );
    ::new( dst ) T( *src );
    src->~T()
}


template<typename T>

void move_vector_buffer( void* dst, T* begin, T* end )
{
    //  Тут выбираем правильное направление обхода и в цикле зовём move_vector_item
}


Ну и для нужных типов переопределяем, как раньше со swap делали.


R>Проще стало возвращать значения из фунцкций — если не отработает RVO/NRVO, по каким-то причинам, то move точно не подведет.

Во-первых, не все быстрые типы хорошо поддаются move.
Скажем, если у нас строчки устроены так, что короткие строки лежат в буфере прямо "на борту" объекта, то их перемещение будет так же дорого, как копирование.
При этом у RVO/NRVO такой проблемы нет.
Я бы предпочёл какие-то средства явно управлять RVO/NRVO, например...


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


Пример прикольный, но представь себе, что был бы метод move у std::vector'а… (И у этого дерева тоже, соответственно)
Какой клиентский код бы усложнился?


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


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

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

Так это была история про то, что move-семантика умеет расползаться...
И, кстати, в рассказанной истории я не совсем понял, в каком месте были такие уж супер-кривые руки?


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

R>Ну это снова к вопросу, что бывают случаи, когда мув семантику поддержать нельзя. Ну да, бывают, и что?
Ну чистый RAII -- это один из этих случаев...
В целом ничего.

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

Ну было бы круто, например, уметь как-то потребовать, что бы RVO\NRVO точно сработало...

На самом деле есть ещё один аспект move-семантики. Связывание неконстантных ссылок с временными объектами.

В С++98 была некоторая несимметричность в том, что константные ссылки с временными объектами связывать было можно, а неконстантные -- нет. Теперь тоже можно, но ещё отдельным, другим способом.
Возможно было бы хорошо суметь как-то сделать так, что бы уменьшить несимметричность, а не увеличить


В общем резюме моего мнения такое:
1) Безусловно move-семантика в stl-коллекциях была нужна и её не хватало. Но, на мой взгляд её надо было вводить на уровне библиотеки, тем более, что сейчас такую move-семантику прибили гвоздями и опять сказали "нет" развитию библиотеки.

2) То, что NRVO/RVO имело какой-то факультативный статус, было криво. Вместо того, что бы сделать его более явным и управляемым, сделали std::move, который не всегда понятно что сделает, да ещё и является ещё одним альтернативным способом для того же самого, что только усложняет поведение компилятора, и без того не простое.

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

4) Сама по себе нынешняя концепция перемещающего конструктора, если вообще считать, что такой нужен, кривая, так как заставляет оставлять на месте источника некое "пустое" состояние. Было бы логичнее в случае вызова какой-то такой конструкции исходный объект РАЗРУШАТЬ...
Правда тогда бы в некоторых случаях было бы что-то недоступно из того, что доступно сейчас. Но мне кажется, что никаких полезных сценариев бы не потерялось...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Есть ли жизнь после перемещения?
От: Videoman Россия https://hts.tv/
Дата: 20.11.18 20:46
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>4) Авторигестрилке приписывают move-конструктор, который заменяет подписчика в списке источника уведомлений, вместо того, что бы массив туда-сюда двигать

E>5) В каких-то случаях случаются странные эффекты при вызовах автосгенерированных move-конструкторов...

Т.е. кто-то не разобрался как правильно реализовывать move семантику и зачем-то неправильно переопределил move-конструктор?

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


Извините, но какой-то сумбур и поток эмоций. Ничего не трогайте, не определяйте и все гарантированно будет работать как и раньше.

E>Классический RAII это объект есть -- ресурс захвачен, объект разрушен -- ресурс освобождён.

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

Если вы пока не решили как с такими состояниями правильно работать, просто не допускайте ручного вызова std::move для l-value.

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


В данном случае поведение смарт-ссылок нечем не отличается от просто-ссылок. Перемещается не ссылка, а сам объект. Если в вашем случае недопустимо такое состояние объекта не используйте std::move для l-value ссылок.

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


Я не уверен, но речь скорее всего идет о std::smart_ptr, где используется атомарный счетчик ссылок внутри.
Но вообще, с приходом move-семантики появилась возможность безопасно выражать в коде поведение объектов которые невозможно скопировать, но можно передать владение ими, например: thread, file, uniqe_ptr и т.д.
Re[7]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 20.11.18 20:59
Оценка:
Здравствуйте, Videoman, Вы писали:

E>>4) Авторигестрилке приписывают move-конструктор, который заменяет подписчика в списке источника уведомлений, вместо того, что бы массив туда-сюда двигать


V>Т.е. кто-то не разобрался как правильно реализовывать move семантику и зачем-то неправильно переопределил move-конструктор?

Почему неправильно?

V>Если вы пока не решили как с такими состояниями правильно работать, просто не допускайте ручного вызова std::move для l-value.

А в move-конструкторе-то что писать?

V>Но вообще, с приходом move-семантики появилась возможность безопасно выражать в коде поведение объектов которые невозможно скопировать, но можно передать владение ими, например: thread, file, uniqe_ptr и т.д.


Почему бы его не выражать просто методом move?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.