Здравствуйте, LaptevVV, Вы писали:
LVV>Вроде как move становится простым как "два байта" переслать.
Наоборот, move усложняется, потому что надо не просто скопировать содержимое, а поправить "указатели на себя".
Именно из-за таких классов move сделан таким сложным, потому что иначе его можно было бы реализовать тупо побитовой копией (а оригинал принудительно делать placement new() на конструктор-по-умолчанию), а вектор можно было бы реаллоцировать полным аналогом сишного реаллок.
И что характерно, именно самоссылающиеся классы как раз не используют в векторах и там где нужен move. Так что получается что кресотмув — переусложнённый ненужный кусок говна.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
LVV>>Вроде как move становится простым как "два байта" переслать. TB>Наоборот, move усложняется, потому что надо не просто скопировать содержимое, а поправить "указатели на себя".
Ну, оно и хорошо — народ прочитает и знать будет.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
TB>Наоборот, move усложняется, потому что надо не просто скопировать содержимое, а поправить "указатели на себя".
Он усложняется уже хотя бы тем, что его нужно написать, в том или ином виде. Тогда как в подавляющем большинстве случаев, для несамореференсных классов, с этим спокойно справляется сам компилятор.
TB>Так что получается что кресотмув — переусложнённый ненужный кусок говна.
+1
--
Справедливость выше закона. А человечность выше справедливости.
вроде как =delete это не решается
копи елижин который появился начиная с С++17
может проходить даже когда стоит запрет на операции копирования и перемещения класса
может конечно бага компилятора, хз
у меня были случая когда с этим сталкивался, под рукой примера нет
правда я уже больше десятка раз обновил и msvc и clang
но Константин Владимиров у себя в уроках тоже показывал похожие примеры
там только наоборот
имплементация есть, но она не вызывается у класа
в целом это было известно
видимо автор по ссылкам наткнулся на этом спустя 8 лет когда вышел стандарт С++17
Здравствуйте, Великий Мессия, Вы писали:
ВМ>вроде как =delete это не решается ВМ>копи елижин который появился начиная с С++17 ВМ>может проходить даже когда стоит запрет на операции копирования и перемещения класса
Если ты про RVO/NRVO, то на нём это никак не должно сказываться, потому что адрес объекта не меняется. Так что даже при запрете на мув, такой код должен отлично работать:
Здравствуйте, T4r4sB, Вы писали:
TB>Если ты про RVO/NRVO, то на нём это никак не должно сказываться, потому что адрес объекта не меняется. Так что даже при запрете на мув, такой код должен отлично работать: TB>
Ну, с другой стороны, никто ведь ничего другого и не обещал. Mandatory (guaranteed) copy/move elision обещано только для RVO. А NRVO как было, так и осталось оптимизацией — т.е. на усмотрение компилятора.
--
Справедливость выше закона. А человечность выше справедливости.
LVV>>https://biowpn.github.io/bioweapon/2025/07/13/this-pointing-classes.html LVV>>Вроде как move становится простым как "два байта" переслать. V>Профессор, при всем уважении, Вам надо как то более качественно изучать материалы которые Вы приносите. Там поинт совсем в другом.
Ну, с этим разобрались...
Но вообще говоря — чего только народу в голову не приходит — извращения всякие...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Но вообще говоря — чего только народу в голову не приходит — извращения всякие...
Я не рискну говорить за всех, но, из моего личного опыта, во всех случаях, когда возникали вот такие самореференсные классы — это всегда был говнодизайн. И всегда получалось перепроектировать.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Я не рискну говорить за всех, но, из моего личного опыта, во всех случаях, когда возникали вот такие самореференсные классы — это всегда был говнодизайн. И всегда получалось перепроектировать.
тот же circular_buffer из примера. Хранили бы size_t head_ вместо T* head_. И вопрос странного перемещения решается сам собой.
Судя по прочитанному это писал новичок в С++.
Жаль, что причина копирования this в поле класса не названа. Как по мне, любая попытка иметь две копии одного и того же данного — это путь к ошибке. Поэтому, в частности, написание кэша — сложная задача.
(Это называется "создать себе трудности и героически их превозмогать").
Нужно понимать, что все на свете объекты бывают трёх видов
— copyable (значение-подобные) — поведение системы не зависит от количества копий
— moveable — поведение не зависит от адреса (но копировать нельзя)
— неподвижные — идентичность определяется адресом
И, хотя контракт "неподвижные" реализовать проще всего, но контракт "значение-подобные" востребован слишком часто, чтобы компилятор дефолтился именно к нему.
Почему объект становится неподвижным — тут могут быть самые разные причины. Ссылки внутрь себя — лишь одни из них.
Другая причина — это внешние ссылки, например.
Когда объект (или его агрегат) принадлежит не только непосредственному владельцу, но и какому-нибудь реестру.
Или когда объекты образуют граф ссылок друг на друга.
Те же виджеты в статье. Виджет — это то, чем владеет движок графического интерфейса. Мы создали объект и движку препоручили.
======
В некоторых случаях можно руками написать — как правильно копировать и/или переносить содержимое с одного места на другое.
Понятное дело, что эти "некоторые" случаи не обобщаются, каждый раз будет разный код.
Альтернатива — это вообще избавиться от необходимости перемещать содержимое.
shared_ptr и unique_ptr (и голые указатели с такой же семантикой, только вручную) превращают объект-фасад в копируемый, а объект-реализацию оставляют неподвижной.
Хотя всё равно копирование содержимого остаётся нетривиальным. Да ещё вылезают кольцевые зависимости.