S>>Вот это, получается, канонический вариант. Но не красивый — добавляет в код угловатости.
M>Конкретно что не устраивает? M>В с++ за владение объектом и его передачу как раз таки отвечает специально для этого придуманный unique_ptr.
Ну вроде и без unique_ptr все работает за счет RVO. Наш авторитет сказал выше что гарантируется стандартом, можно опираться на это. Т.е. если можно написать проще — то нужно писать проще, без доп. оберток.
Здравствуйте, Shmj, Вы писали:
M>>Конкретно что не устраивает? M>>В с++ за владение объектом и его передачу как раз таки отвечает специально для этого придуманный unique_ptr.
S>Ну вроде и без unique_ptr все работает за счет RVO. Наш авторитет сказал выше что гарантируется стандартом, можно опираться на это. Т.е. если можно написать проще — то нужно писать проще, без доп. оберток.
На самом деле, вариант с умным указателем ближе к привычным тебе ссылочным типам. С shared_ptr было бы ещё ближе. С двумя лишь отличиями: детерминированность времени жизни (это плюс) и неспособность разруливать циклические зависимости (это минус, который частично можно компенсировать использованием weak_ptr).
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>На самом деле, вариант с умным указателем ближе к привычным тебе ссылочным типам. С shared_ptr было бы ещё ближе. С двумя лишь отличиями: детерминированность времени жизни (это плюс) и неспособность разруливать циклические зависимости (это минус, который частично можно компенсировать использованием weak_ptr).
Т.е. оно в принципе можно и std::option<std::reference_wrapper<Obj1>> писать и получить фактически те же удобные ссылки без доп. нагрузки на управление памятью. Или умные указатели — так же фактически все делает за тебя.
Но! Добавляется невыразительность и угловатость кода на пустом месте.
S>Т.е. оно в принципе можно и std::option<std::reference_wrapper<Obj1>> писать и получить фактически те же удобные ссылки без доп. нагрузки на управление памятью. Или умные указатели — так же фактически все делает за тебя.
S>Но! Добавляется невыразительность и угловатость кода на пустом месте.
А, вот ты о чём. Тоже мне, проблема. Алиасы же есть:
S>Т.е. оно в принципе можно и std::option<std::reference_wrapper<Obj1>> писать и получить фактически те же удобные ссылки без доп. нагрузки на управление памятью
Угу, а можно на потолке спать. Ты, походу, вообще предмет не просекаешь, раз пишешь эту дичь.
Если хочешь, чтоб я тебе пояснил, чего именно ты не понимаешь, перепиши вот этот свой фрагмент с использованием std::option<std::reference_wrapper<Obj1>> и я подробно тебе всё разжую. А может, дойдешь самостоятельно.
Здравствуйте, Shmj, Вы писали:
S>Все-равно не наглядно и не удобно — держать в памяти все эти алиасы. Если бы он один был на проект то ОК. Но их же будет плодиться как мух.
Просто не нужно делать область видимости имен больше, чем это реально нужно, и всё будет норм. И это относится не только к алиасам, а вообще ко всем именам.
--
Справедливость выше закона. А человечность выше справедливости.
Конструкторы копирования/перемещения здесь ни разу не понадобились даже формально.
Ты можешь даже явно удалить их, и убедиться в этом. Фактически, ты просто разжился rvalue-ссылкой, но нигде ею не воспользовался для перемещений.
Если бы передавал по значению, то в некоторых местах мог бы словить оптимизацию copy elision. То есть, компилятору формально нужны конструкторы, но он ими не воспользуется.
Не надо бояться промежуточных копирований, а тем более, промежуточных перемещений.
Если объект сам по себе не слишком большого размера, то даже если компилятор не оптимизирует размещение его промежуточных копий, то правильно написанный (а в ряде случаев — реализованный по умолчанию) конструктор перемещения не отнимет много процессорного времени.
Всякие там std::vector прекрасно перемещаются сами — передавая своё содержимое от одного экземпляра другому.
Объекты надо возвращать (и желательно, принимать тоже) по значению, а не по rvalue-ссылке.
Так ты с большей гарантией не получишь висячую ссылку, как в коде примера.
Соответственно, дизайн кода у обёртки — например, такой
Здесь мы говорим, что ссылка на поле — временная, поэтому конструктор возвращаемого значения — это конструктор перемещения. То есть, можно украсть контент.
Если же объект реально тяжеловесный сам по себе, и не хочется морочить голову вопросами его перемещения — то умные указатели тебе в помощь. Заодно и работу со стеком разгрузишь.
std::unique_ptr не имеет конструктора копирования, так что заодно получишь диагностику от компилятора обо всех местах, где ты явно или неявно пытался копировать вместо перемещения. Ну и там, где нужно именно копирование, — сделаешь его руками.
Здравствуйте, Кодт, Вы писали:
К>Если же объект реально тяжеловесный сам по себе, и не хочется морочить голову вопросами его перемещения — то умные указатели тебе в помощь. Заодно и работу со стеком разгрузишь.
Так std:vector же хранит свои большие данные (сам массив) — не в стеке а в куче, даже если сам vector создан в стеке. И если RVO работает — то зачем лишние обертки?
S>Т.е. если можно написать проще — то нужно писать проще, без доп. оберток.
Если основной критерий выбора языка это простота, то как ты вообще оказался на этом форуме?
Я думал тебе нужен перформанс и максимальная кроссплатформенность.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, Кодт, Вы писали:
К>>Если же объект реально тяжеловесный сам по себе, и не хочется морочить голову вопросами его перемещения — то умные указатели тебе в помощь. Заодно и работу со стеком разгрузишь.
S>Так std:vector же хранит свои большие данные (сам массив) — не в стеке а в куче, даже если сам vector создан в стеке. И если RVO работает — то зачем лишние обертки?
У тебя вообще в плане дизайна весь код какой-то кривой. Всякие там getdata это как правило хреновый дизайн. Всегда можно без этого сделать компактнее и яснее
Здравствуйте, Shmj, Вы писали:
К>>Если же объект реально тяжеловесный сам по себе, и не хочется морочить голову вопросами его перемещения — то умные указатели тебе в помощь. Заодно и работу со стеком разгрузишь. S>Так std:vector же хранит свои большие данные (сам массив) — не в стеке а в куче, даже если сам vector создан в стеке. И если RVO работает — то зачем лишние обертки?
Так вот вектор не тяжеловесный сам по себе. Что там внутри, один указатель и два размера.
Поэтому там конструктор перемещения сводится к трём операциям обмена.
Но если у тебя какая-нибудь мега-структура с множеством полей, которые нужно как-то копировать-переносить, — то моли бога, чтобы её можно было оптимизировать до memcpy.
А уж если эти поля с нетривиальными конструкторами...
По сути, использовать unique_ptr (или shared_ptr, возможно, в тандеме с CopyOnWrite) — это такие разновидности идиомы PIMPL. Лёгкий фасад и тяжёлая реализация (в том числе, реализация копирования).
Здравствуйте, __kot2, Вы писали:
S>>Так std:vector же хранит свои большие данные (сам массив) — не в стеке а в куче, даже если сам vector создан в стеке. И если RVO работает — то зачем лишние обертки? __>У тебя вообще в плане дизайна весь код какой-то кривой. Всякие там getdata это как правило хреновый дизайн. Всегда можно без этого сделать компактнее и яснее
Здравствуйте, Кодт, Вы писали:
К>Так вот вектор не тяжеловесный сам по себе. Что там внутри, один указатель и два размера. К>Поэтому там конструктор перемещения сводится к трём операциям обмена.
Но это перемещения. А ведь копирование может быть весьма затратным, там же и гигабаты могут быть.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, __kot2, Вы писали:
S>>>Так std:vector же хранит свои большие данные (сам массив) — не в стеке а в куче, даже если сам vector создан в стеке. И если RVO работает — то зачем лишние обертки? __>>У тебя вообще в плане дизайна весь код какой-то кривой. Всякие там getdata это как правило хреновый дизайн. Всегда можно без этого сделать компактнее и яснее
S>На пример как?
Для этого нужно целиком задачу понимать. Сформулируй ее как нить более цельно
Здравствуйте, __kot2, Вы писали:
S>>На пример как? __>Для этого нужно целиком задачу понимать. Сформулируй ее как нить более цельно
Сетевой бинарный пакет. С помощью методов устанавливаем удобным образом отдельные части пакета — как то версия, тип пакета и пр. Но так же должна быть возможность получить данные пакета целиком для отправки (или предварительного шифрования).
S>Сетевой бинарный пакет. С помощью методов устанавливаем удобным образом отдельные части пакета — как то версия, тип пакета и пр. Но так же должна быть возможность получить данные пакета целиком для отправки (или предварительного шифрования).
У меня знакомый делал подобную задачу. Задаётся type_id константой, задаётся низлежащий тип, так же может быть вектор подобных значений. Он её делал как тестовое. У него всё вычислялось в компайл-тайме, и вообще, код бы на порядок, не, на два, лучше. За день вроде сделал.
Здравствуйте, Marty, Вы писали:
M>У меня знакомый делал подобную задачу. Задаётся type_id константой, задаётся низлежащий тип, так же может быть вектор подобных значений. Он её делал как тестовое. У него всё вычислялось в компайл-тайме, и вообще, код бы на порядок, не, на два, лучше. За день вроде сделал.
В компил-тайме не получится, т.к. тип пакета узнаю на основе поступающих данных.