Re[15]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 11:43
Оценка:
Здравствуйте, rg45, Вы писали:

R>1) Обязывает предоставлять дефолтный конструктор, что не всегда приемлемо;

R>3) Содержит оверхед на создание никому ненужного состояния объекта;
А чем плох конструктор по умолчанию? На мой взгляд плох не такой конструктор, а то, что нужно поддерживать в классе некое выделенное "значение по умолчанию".
Ну так move-конструктор тоже требует поддержать такое значение же?
В этом смысле я вообще не вижу разницы в подходах.
Но если говорить о попытках выпрямить невозможность перемещения содержимого вектора, то плюс такой, что вообще не надо менять язык.

Но если таки менять, то если бы как-то разрешили описывать конструкции вроде RVO, например, то есть я бы сам мог написать функцию, которой можно было бы передать буфер для конструирования там результата, и её потом было бы удобно вызывать, то ты бы мог написать так, как тебе нравится и не вводя конструктор перемещения.

Да, для конструктора перемещения надо ещё, обычно, и парный метод присваивания, кстати. И в месте вызова всегда трудно понять перемещение будет вызвано или копирование.

R>2) Вводит необоснованные ограничения на использование ссылок и констант в качестве членов классов;

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

R>4) Реализуется с использованием функции-члена, что противоречит принципам обобщенного программированя;

Конечно же конструктор-копии -- это не функция-член
В любом случае, если мы хотим написать функцию, которая "крадёт" данные из объекта, она должна иметь доступ к private-части класса.

R>5) Резервирует имя функции-члена, создвавая предпосылки для конфликтов имен;

R>6) Плохо подходит для работы с разными типами данных. Как только src и dst станут иметь разные тут же выяснится, что в каких-то случаях удобнее иметь "move_to", а каких-то "move_from";
Так это же означает, что в случае конструктора копии удобный вариант в половине случаев вообще не получится выбрать.
Он вообще всегда имеет только вариант move_from, называемый "перемещающий оператор присваивания"
Кстати, я уже выше писал, что согласен, что просто move плохое название для такого метода. Лучше, конечно move_to/move_from/swap

R>7) Не подходит для автоматической генерации компилятором. Пониммаю, что для тебя это плюс, но не разделяю твою точку зрения. Потому, что сейчас поддержка move семантики в большинстве случаев либо генерируется автоматически, либо сводится к тривиальному разрешить/запретить. В твоем же варианте реально нужно будет все это писать. Раздувая объем кода и натягивая массу ошибок;

Это место я не понял. Ты про то, что в STL-контейнерах Степанов забыл поддержать такую возможность, как move_to, или про что?


R>8) Вынуждает заводить лишние локальные переменные, что крайне плохо сказывается на структуре кода.


Это тоже не понял. Но как переменная (имеющая имя и смысл) портит структуру кода, ни зачем их заводить?

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

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


Плох не конструктор сам по себе, а то, что он становится обязательным. Появляется ограничение там, где его раньше не было. Бывают такие классы, для которых конструкторы по умолчанию лишены смысла, и их поддержка наносит прямой вред.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 23.11.2018 11:49 rg45 . Предыдущая версия .
Re[15]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 11:48
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Т.е. dst уже ложен быть на момент создания. А как через такой синтаксис выразить:

V>
V>SomeClass b = ....
V>//...
V>SomeClass a = b + SomeClass(...); // такое?
V>

Такое прекрасно работало и до move-семантики через RVO и copy elision…


V>
V>SomeClass a = ....
V>func(std::move(a)); // такое?
V>

Такой, на мой вкус, вообще сомнительно. Смотри, например, вопрос о том, с чего началась эта ветка...

V>А что делать если нам не повезло и у dst нет конструктора по умолчанию? И src у тебя превращается в такое же зомби с неопределенным состоянием. Так чем же твой подход лучше?

Тем, что не надо усложнять язык...
Хуже то, что в этом раскладе move-семантика ничем не лучше, но сложнее

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

Но я в плоском режиме читаю, могу подветки спутать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Отредактировано 23.11.2018 12:38 Erop . Предыдущая версия . Еще …
Отредактировано 23.11.2018 12:33 Erop . Предыдущая версия .
Re[13]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 11:50
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Причём тут RVO? Или это вы так copy elision называете?


Ну всю группу таких оптимизаций. RVO, NRVO, copy elision и т. д...
В С++ часто бывает так, что мы вместо того, что бы несколько раз копировать созданный объект, сразу создаём его в нужном месте.

Но формально там среди нескольких конструкторов была и функция ну и operator + у класса тоже как бы функция или метод


p. s.
Тут вроде на "ты" обращение принято?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Отредактировано 23.11.2018 12:36 Erop . Предыдущая версия . Еще …
Отредактировано 23.11.2018 12:34 Erop . Предыдущая версия .
Re[15]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 12:03
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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


E>>То, что у нас, как программистов на С++ нет механизмов для прямого написания похожих функций, ну, например, мы не можем написать метод move_to_res(), который возвращает объект, в который перемещает себя.

E>>Ну, то есть мы сейчас можем написать { return std::move(*this); }
E>>Но для этого нам надо писать конструктор перемещения и всё такое. Напрямую мы такую функцию написать не можем.
BFE>Можем:
Во-первых, этот код вовсе не перемещает себя в результат, он просто возвращает хитрую ссылку на себя же:
Я заменил печать на
  std::cout << "&  a" <<   &a << " -- ok\n";
  std::cout << "&rrA" << &rrA << " -- ok\n";
и ожидаемо получил
&  a0x7fff2679d2ff -- ok
&rrA0x7fff2679d2ff -- ok


Смотри: https://www.ideone.com/0kG6yM

Во-вторых, это вовсе и не "напрямую"...
Напрямую было бы, например, если бы я передавал в функцию адрес (или как-то внутри функции мог бы его получить) того места, где ловят результат снаружи.
Как с this в конструкторах сделано, например...
Кстати, при таком подходе можно было бы возвращать сразу несколько результатов.

E>>Что касается критики идеи с методом move у вектора, то код
std::vector<T> dst;
E>>src.move_to( dst )
ничем особо не хуже метода
std::vector<T> dst = std::move( src );
кроме того, что первое сразу понятно, а второе надо знать пр std::move, конструкторы перемещения и т. д...

BFE>А как быть, если dst — аргумент функции?
А что от этого меняется? Ты правда пытаешься оспорть то, что в контейнерах можно было поддержать возможность move чисто сресдствами библиотеки, не меняя языка?
И это при живых методе и функции swap?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[17]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 12:12
Оценка:
Здравствуйте, rg45, Вы писали:

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



Так конструктор перемещения плох примерно тем же жеж?

Мне, на самом деле, вообще концепция перегруженных конструкторов не особо нравится. Так как функция одинаково называется/вызывается, а делать может разное. Это противоречит обычной практике перегрузки функций...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 23.11.18 12:25
Оценка:
Здравствуйте, Erop, Вы писали:

E>Так конструктор перемещения плох примерно тем же жеж?


С чего вдруг? У конструктора такие же возможности по инициализации любых членов-данных, в т.ч. ссылок и констант, как и у любого другого конструктора. Только, в отличие от конструктора по умолчанию, у него есть входные данные для такй инициализации.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[19]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 12:35
Оценка:
Здравствуйте, rg45, Вы писали:

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


С того, что он должен оставить "зомби" на старом месте? Или там пофиг чем константы/ссылки инициализированы? Например ссылки на несуществующие объекты -- это нормально?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[20]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 23.11.18 12:45
Оценка:
Здравствуйте, Erop, Вы писали:

E>С того, что он должен оставить "зомби" на старом месте? Или там пофиг чем константы/ссылки инициализированы? Например ссылки на несуществующие объекты -- это нормально?


Не "должен", а "может". Важно, что есть возможность полноценно сконструировать новый объект. А что именно остается на старом месте ни чем регламентировано, это может быть что угодно — от полного копирования, до полной выемки всех данных. Собственно, в этом мой вопрос и заключался — что может, а чего не может оставаться на старом месте после перемещения.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[14]: Есть ли жизнь после перемещения?
От: Videoman Россия https://hts.tv/
Дата: 23.11.18 13:09
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>Так что и дальше можно обсуждать механизмы по управлению RVO...

V>>Ну вот приведи разумный пример, когда RVO не нужна?
E>Не понял, что значит "не нужна"?

Ну ты хочешь зачем-то управлять RVO. RVO применяется всегда, когда это возможно — значит ты хочешь RVO отключать

E>Ну я же приводил пример. У тебя есть авторегистрилки и уведомлялки.

E>Когда ты из них выводишь объекты, которые получают и рассылают эти все уведомления, и потом их копируешь дефолтным конструктором копии, то в момент создания копии весь оригинал ещё существует в виде MDT, и он весь корректно работает и все рассылки уведомлений между его частями тоже. А когда ты перемещаешь конструктором перемещения, то в процессе перемещения какие-то части уже подписаны, а какие-то ещё нет, в результате инварианты вроде "всех уведомили о" могут теряться...

Не, ну тут у тебя явно ошибка в логике. Ты где-то перемещаешь "душу", а this у тебя где-то старый зависает. Это не относится только к move-у. Совет, используй в таких случаях Impl и всю подписку делай в нем, тогда таких проблем не будет, т.к. он мувается на ура.

E>Я понял в чём суть разногласий. Ты считаешь, что move-семантику ввели практически за бесплатно, а я считаю, что усложнили и весьма заметно, язык.


Да, видимо так. Но все у меня все стало хорошо, как только я перестал переть против "паровоза", немного вник и стал действовать в русле разработчиков стандарта С++.

E>Да, STL -- штука весьма кривая. Это правда.

Re[21]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 20:12
Оценка:
Здравствуйте, rg45, Вы писали:

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



Ну ты же понимаешь, что на старом месте позовут потом деструктор?..

Это как бы единственное ограничение.

Но если оставить что-то такое, с чем потом легко злоупотребить, например ссылку на несуществующий объект, то легко устроить потом нечаянно большой бара-бум, как говорила героиня Миллы Йолович в "Пятом элементе"
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[15]: Есть ли жизнь после перемещения?
От: Erop Россия  
Дата: 23.11.18 20:20
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Ну ты хочешь зачем-то управлять RVO. RVO применяется всегда, когда это возможно — значит ты хочешь RVO отключать

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

Я приводил несколько вариантов возможного управления механизмами вроде RVO тут, в дискуссии, если что.

V>Не, ну тут у тебя явно ошибка в логике. Ты где-то перемещаешь "душу", а this у тебя где-то старый зависает. Это не относится только к move-у. Совет, используй в таких случаях Impl и всю подписку делай в нем, тогда таких проблем не будет, т.к. он мувается на ура.


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

V>Да, видимо так. Но все у меня все стало хорошо, как только я перестал переть против "паровоза", немного вник и стал действовать в русле разработчиков стандарта С++.

Я тоже не "пру против паровоза", хотя в том проекте, где я широко пользовался С++ крайний раз, STL не использовался, по многим причинам

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

E>>Да, STL -- штука весьма кривая. Это правда.

V>

Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Есть ли жизнь после перемещения?
От: Evgeny.Panasyuk Россия  
Дата: 24.11.18 07:53
Оценка: 18 (1)
Здравствуйте, rg45, Вы писали:

TSP>>В писании сказано:

TSP>>

TSP>>Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

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

Для объектов стандартной библиотеки "valid" означает что им можно продолжать пользоваться. Например вектору легально можно сделать .clear(), или .resize(), .size().

R>Этот вопрос можно сформулировать и по-другому: стоит ли требовать от разработчиков, в самом общем случае, документирования состояния объектов после перемещениея?


Документировать конечно стоит. Причём "документацией" может быть одно предложение на весь проект а-ля "Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state".

R>Или исплользование объектов после перемещения — это зло, с которым нужно бороться?


Нет, не зло если разрешено документацией.

R>Или могут быть варианты?

R>P.S. Понятно, что из любого правила могут быть исключения. Но хотелось бы понимать, все-таки, каково же само правило.

Правило стандартной библиотеки привели выше.
Если в проекте используется такая же конвенция как и в стандартной библиотеке, то для тех типов для которых это не выполняется (т.е. "Unless otherwise specified") — может в Debug режиме добавить в методы assert(this->is_valid()).

Если брать непосредственно технический аспект rvalue references — то думаю даже destructability не является формальным требованием языка, а вызов методов не является формальным запретом.

В большинстве же случаев ожидается как минимум нормальная desctructability и возможность move assignment.
Re[10]: Есть ли жизнь после перемещения?
От: Evgeny.Panasyuk Россия  
Дата: 24.11.18 08:08
Оценка: 9 (1)
Здравствуйте, Erop, Вы писали:

V>>Зачем управлять тем, чем компилятор и так управляет оптимально:

V>>- сначала пробует RVO/NRVO
E>Например было бы круто как-то сказать компилятору, что в этом месте надо обломаться, если не получилось.
E>И в этом случае, кстати, можно было бы не требовать наличие открытого конструктора копии

Начиная с C++11 есть list-initialization:
live demo
struct NonCopyableNonMovable
{
    NonCopyableNonMovable(int, double){}

    NonCopyableNonMovable(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable(const NonCopyableNonMovable &) = delete;

    NonCopyableNonMovable &operator=(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable &operator=(const NonCopyableNonMovable &) = delete;
};

NonCopyableNonMovable foo()
{
    return {1, .5};
}

int main()
{
    auto &&x = foo();
}


А начиная с C++17 есть гарантированное RVO:
live demo
struct NonCopyableNonMovable
{
    NonCopyableNonMovable(int, double){}

    NonCopyableNonMovable(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable(const NonCopyableNonMovable &) = delete;

    NonCopyableNonMovable &operator=(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable &operator=(const NonCopyableNonMovable &) = delete;
};

NonCopyableNonMovable foo()
{
    return NonCopyableNonMovable{1, .5};
}

int main()
{
    auto x = foo();
}
Re[11]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 24.11.18 11:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>А начиная с C++17 есть гарантированное RVO:

EP>live demo
EP>
EP>NonCopyableNonMovable foo()
EP>{
EP>    return NonCopyableNonMovable{1, .5};
EP>}

EP>int main()
EP>{
EP>    auto x = foo();
EP>}
EP>


Разрыв шаблонов и подрыв устоев какой-то

И что в таком случае должно помешать сделать вот так?:

int main()
{
    NonCopyableNonMovable t{1, .5};
    auto x = std::move(t);
}

Разница ведь между std::move и foo только в том, что std::move возвращает rvalue ссылку, тогда как foo возвращает по значению. Теперь эти случаи будут обрабатываться по разным правилам?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[12]: Есть ли жизнь после перемещения?
От: Evgeny.Panasyuk Россия  
Дата: 24.11.18 12:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>И что в таком случае должно помешать сделать вот так?:


R>
R>int main()
R>{
R>    NonCopyableNonMovable t{1, .5};
R>    auto x = std::move(t);
R>}
R>


Конкретно в этом примере нужен конструктор перемещения, ибо t всё ещё жив, точнее там в области живы оба объекта.

R>Разница ведь между std::move и foo только в том, что std::move возвращает rvalue ссылку, тогда как foo возвращает по значению.


Вот упрощённый пример:
live demo
struct NonCopyableNonMovable
{
    NonCopyableNonMovable(int, double){}

    NonCopyableNonMovable(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable(const NonCopyableNonMovable &) = delete;

    NonCopyableNonMovable &operator=(NonCopyableNonMovable &&) = delete;
    NonCopyableNonMovable &operator=(const NonCopyableNonMovable &) = delete;
};

NonCopyableNonMovable foo();

NonCopyableNonMovable &&bar();

int main()
{
    auto   x = foo(); // C++11: fails to compile | C++17: compiles OK
    auto &&y = foo(); // C++11: compiles OK      | C++17: compiles OK
    auto   z = bar(); // C++11: fails to compile | C++17: fails to compile
    auto &&t = bar(); // C++11: compiles OK      | C++17: compiles OK
}


R>Теперь эти случаи будут обрабатываться по разным правилам?


Теперь при возврате по значению И сохранению по значению компилируется, а раньше нет — ибо теперь возможно гарантированное RVO.
Re[13]: Есть ли жизнь после перемещения?
От: rg45 СССР  
Дата: 24.11.18 12:47
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Теперь при возврате по значению И сохранению по значению компилируется, а раньше нет — ибо теперь возможно гарантированное RVO.


Принцип я понял. И, безусловно, рад такой возможности. Но меня интересовало, как эти требования будут сформулированы в стандарте. Но вот что-то не находится в драфте 17-го ни "RVO", ни "return value optimization".
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[14]: Есть ли жизнь после перемещения?
От: Evgeny.Panasyuk Россия  
Дата: 24.11.18 13:24
Оценка:
Здравствуйте, rg45, Вы писали:

R>Принцип я понял. И, безусловно, рад такой возможности. Но меня интересовало, как эти требования будут сформулированы в стандарте. Но вот что-то не находится в драфте 17-го ни "RVO", ни "return value optimization".


В стандарте используется термин copy/move elision.
Re[14]: Есть ли жизнь после перемещения?
От: σ  
Дата: 24.11.18 19:15
Оценка:
R>Принцип я понял. И, безусловно, рад такой возможности. Но меня интересовало, как эти требования будут сформулированы в стандарте. Но вот что-то не находится в драфте 17-го ни "RVO", ни "return value optimization".

Да и SFINAE в стандарте не находится. И много чего ещё.
Re[13]: Есть ли жизнь после перемещения?
От: Mystic Artifact  
Дата: 24.11.18 23:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Теперь при возврате по значению И сохранению по значению компилируется, а раньше нет — ибо теперь возможно гарантированное RVO.

И за счет чего это достигается? Работает ли это при кросс-модульной не PGO компиляции?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.