Russian Qt Forum

Программирование => С/C++ => Тема начата: ViTech от Февраль 04, 2020, 16:36



Название: C++ Object Token Library
Отправлено: ViTech от Февраль 04, 2020, 16:36
C++ Object Token Library (https://gitlab.com/CppObjectTokens/Module/Library/CppOtl) - это эволюция Unified Pointer Library из этой темы (http://www.prog.org.ru/topic_32109_0.html).

Основные изменения:
  • Терминология: pointer -> object token.
  • Все токены по умолчанию single, а не optional.
  • Удалён safe::weak_single.
  • Добавлен slim::unique (обёртка над std::unique_ptr).
  • Добавлены raw::weak, raw::unified (обёртки над голым указателем).
  • Функции для унифицированного доступа к токенам.
  • Traits.
  • Что-то ещё :).


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 06, 2020, 07:19
Несомненно, реализация стала более стройной и интересной). В том числе и понятие токена выглядит более гармонично, чем понятие указателя.
Программная реализация ассоциативных связей агрегации стала ближе к объектно-ориентированной модели.

После беглого просмотра осталось несколько вопросов:

- Токены реализуют только ассоциативные связи агрегации?
- Экземпляры, которыми владеют/ссылаются токены, всегда формируются в куче?
- Можно ли связать токены и произвольную переменную?
- Можно ли связать токены и произвольный параметр?


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 06, 2020, 11:47
- Токены реализуют только ассоциативные связи агрегации?

Текущий набор токенов предназначен в основном для выражения ассоциативных связей и написания программ в стиле ООП. Но можно применять и в функциональном программировании, с учётом понимания особенностей токенов. Кроме того, можно добавлять типы токенов не связанных с ассоциативными связями. У меня есть идеи для таких токенов, но пока у меня нет в них надобности, я их и не делал.

- Экземпляры, которыми владеют/ссылаются токены, всегда формируются в куче?

Сейчас владеющие токены да, только для объектов в куче. raw::weak/raw::unified могут ссылаться на объекты на стеке. Про владеющие токены для объектов на стеке нужно думать отдельно, чтобы поведение токенов было согласованным. Основные проблемы возникают при перемещении объекта.

- Можно ли связать токены и произвольную переменную?
- Можно ли связать токены и произвольный параметр?

Не совсем понял эти вопросы, хорошо бы привести примеры :). raw::weak/raw::unified можно связать со всем, что имеет адрес. Под свою ответственность разумеется :).

В целом, не нужно пугаться этих заумных слов про ассоциативные связи, агрегации, UML и прочее. Токены из CppOtl - это аналог умных и голых указателей С++, с расширенными возможностями. Поэтому в первой библиотеке Unified Pointer Library они указателями и назывались :).


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 06, 2020, 13:41
не очевидно, нафига нужна эта библиотека.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 06, 2020, 13:53
не очевидно, нафига нужна эта библиотека.

Если вы прочитали всё документацию по ссылке и не нашли ничего полезного для себя, значит вам она не нужна. Что не отменяет факта её возможной полезности для других людей :).


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 06, 2020, 16:14
В том числе и понятие токена выглядит более гармонично, чем понятие указателя.
Не сказал бы, лично к меня "токен" стойко ассоциируется со строками и синтаксическим разбором.

Что не отменяет факта её возможной полезности для других людей :).
Ну кол-во пользователей Вашей библиотеки всегда будет исчисляться простым натуральным числом :) Это проблема ЛЮБОГО велика - да, возможно он решает насущные проблемы, и совсем не исключено что намного лучше чем занюханная стандартная библиотека. НО дальше этого он никуда не пойдет. Поясняю на живом примере:

Вот Вы стали бы использовать МОЙ код? :) Думаю что НИКОГДА, даже без разницы чему он посвящен. Потому что Вы же пишете (намного) лучше, знаете (намного) больше и.т.п :) Да и чисто объективно обычно лучше "подсмотреть идею" чем пристраивать посторонку. А вот std - да, использовать будут, даже если полный кал - но стандартный, и это мощнейшая отмазка, которой у Вас, увы, нет. Если человек работает в проекте вместе с Вами, то std код катит, а вот самопал - себе дороже. Не обязан человек его знать/учить, а вот (сраное) std - обязан.

Думаете кто-то рассуждает иначе? Вот ssoft относится к Вашей затее весьма позитивно и конструктивно, спросите у него задействует ли он эту либу в своем проекте? Конечно могу лишь предполагать, но думается ответ будет типа "все не так просто" - и это нормально


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 06, 2020, 16:50
Не сказал бы, лично к меня "токен" стойко ассоциируется со строками и синтаксическим разбором.

Токен вообще много к чему приплетают :). В UML пишут про object token, оттуда и пошло.

Ну кол-во пользователей Вашей библиотеки всегда будет исчисляться простым натуральным числом :) Это проблема ЛЮБОГО велика - да, возможно он решает насущные проблемы, и совсем не исключено что намного лучше чем занюханная стандартная библиотека. НО дальше этого он никуда не пойдет. Поясняю на живом примере:

Вот Вы стали бы использовать МОЙ код? :) Думаю что НИКОГДА, даже без разницы чему он посвящен. Потому что Вы же пишете (намного) лучше, знаете (намного) больше и.т.п :) Да и чисто объективно обычно лучше "подсмотреть идею" чем пристраивать посторонку. А вот std - да, использовать будут, даже если полный кал - но стандартный, и это мощнейшая отмазка, которой у Вас, увы, нет. Если человек работает в проекте вместе с Вами, то std код катит, а вот самопал - себе дороже. Не обязан человек его знать/учить, а вот (сраное) std - обязан.

Думаете кто-то рассуждает иначе? Вот ssoft относится к Вашей затее весьма позитивно и конструктивно, спросите у него задействует ли он эту либу в своем проекте? Конечно могу лишь предполагать, но думается ответ будет типа "все не так просто" - и это нормально.

Использование сторонней библиотеки всегда риск. Эту библиотеку я делаю для себя. Мне важно, чтобы я мог использовать такую функциональность в проектах, в которых я принимаю участие. И мне не жалко поделиться этими наработками с другими. Чтобы показать, что на С++ можно писать вот так, с меньшими страданиями :). Если на её основе сделают что-то покруче, так на здоровье. Будут ли ей пользоваться другие, меня уже меньше волнует. Как говорится: моё дело предложить :).

Ну а пока напомню, что gsl::not_null<std::unique_ptr> до сих пор не работает. А на днях из gsl::not_null удалили конструктор перемещения (нашёл этот pull request (https://github.com/microsoft/GSL/pull/842)). Похоже, у них своё видение not_null семантики. И std::observer_ptr (https://en.cppreference.com/w/cpp/experimental/observer_ptr) в C++20 так и не вошёл, насколько я понял. И что-то я не вижу подвижек на этом поле в сторону выразительности умных и не очень указателей. Если кто знает такие - сообщайте.


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 07, 2020, 10:09
Не сказал бы, лично к меня "токен" стойко ассоциируется со строками и синтаксическим разбором.

Если я правильно понимаю вопрос), то токен объекта - это то с помощью чего можно обратиться к экземпляру. То есть в контексте программы в записи
Код:
int value = 1;
int - тип, 1 - значение, value - токен, с помощью которого можно осуществить доступ к значению 1. При этом в зависимости от места записи, value может являться свойством (property), параметром (parameter) или переменной (variable).

Вот ssoft относится к Вашей затее весьма позитивно и конструктивно, спросите у него задействует ли он эту либу в своем проекте? Конечно могу лишь предполагать, но думается ответ будет типа "все не так просто" - и это нормально

Действительно, реализация мне интересна больше с академической точки зрения, но только потому, что я не разделяю идею использования аналога указателей в качестве токенов. Основной причиной считаю, что указатель является семантически неверным с точки зрения модели ООП. Но огромное количество разработчиков даже не думает об этом (не забивают себе мозг всякой ерундой  ;) ) - используют всё, что есть под рукой, совершенно не задумываясь об ассоциативных связях, согласованности и непротиворечивости объектно-ориентированной модели.

Тем не менее, C++ Object Token Library достаточно близка по виду к умным указателям std, при этом дополнительно решает ряд задач:

- корректно согласует модельное понятие агрегации shared, composite, none (shared, unique, weak) с технически механизмом продления жизни;
- обеспечивает гарантированную мультипликативность (single, optional);
- ликвидирует необходимость прямой работы с нативными указателями.

По виду указателя нельзя однозначно определить, что из себя он представляет - значение, массив, ассоциативная связь. Умные указатели std - это одно из частных решений для замены нативных, не всегда удобное, так как добавляет ряд свойств и ограничений применения (memory heap, optional и др.).

Реализация C++ Object Token Library добавляет механизмы управления такими свойствами, как (single/optional, продление времени жизни), но не такими как (thread safe, lazy/cow и т.д.).
Для тех кому важно, чтобы реализация программы как можно ближе соответствовала ее модели, эти примитивы могут быть весьма полезными.


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 07, 2020, 10:23
ssoft
Красиво заливаете, кажется, стоит посмотреь этого зверя :)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 07, 2020, 10:56
Если я правильно понимаю вопрос), то токен объекта - это то с помощью чего можно обратиться к экземпляру. То есть в контексте программы в записи
Код:
int value = 1;
int - тип, 1 - значение, value - токен, с помощью которого можно осуществить доступ к значению 1. При этом в зависимости от места записи, value может являться свойством (property), параметром (parameter) или переменной (variable).

Самое интересное, что в UML токен объекта описан в общих чертах:
15.2.3.1 Activities (UML (https://www.omg.org/spec/UML/2.5.1/PDF))
Цитировать
Tokens are not explicitly modeled in an Activity, but are used for describing the execution of an Activity. An object token is a container for a value that flows over ObjectFlow edges (some object tokens can flow over ControlFlow edges, as specified by the modeler, see isControlType for ObjectNodes in sub clause 15.4). An object token with no value in it is called a null token.

Т.е. токен объекта - это контейнер, и моделируйте/реализуйте его как хотите :).

Тем не менее, C++ Object Token Library достаточно близка по виду к умным указателям std, при этом дополнительно решает ряд задач:

- корректно согласует модельное понятие агрегации shared, composite, none (shared, unique, weak) с технически механизмом продления жизни;
- обеспечивает гарантированную мультипликативность (single, optional);
- ликвидирует необходимость прямой работы с нативными указателями.

По виду указателя нельзя однозначно определить, что из себя он представляет - значение, массив, ассоциативная связь. Умные указатели std - это одно из частных решений для замены нативных, не всегда удобное, так как добавляет ряд свойств и ограничений применения (memory heap, optional и др.).

Реализация C++ Object Token Library добавляет механизмы управления такими свойствами, как (single/optional, продление времени жизни), но не такими как (thread safe, lazy/cow и т.д.).
Для тех кому важно, чтобы реализация программы как можно ближе соответствовала ее модели, эти примитивы могут быть весьма полезными.

Спасибо за отзыв :).

Действительно, реализация мне интересна больше с академической точки зрения, но только потому, что я не разделяю идею использования аналога указателей в качестве токенов. Основной причиной считаю, что указатель является семантически неверным с точки зрения модели ООП. Но огромное количество разработчиков даже не думает об этом (не забивают себе мозг всякой ерундой  ;) ) - используют всё, что есть под рукой, совершенно не задумываясь об ассоциативных связях, согласованности и непротиворечивости объектно-ориентированной модели.

Я, кстати, тоже не разделяю идею использования аналога указателей в качестве токенов :). Об этом говорится в разделе Access (https://gitlab.com/CppObjectTokens/Module/Library/CppOtl/-/blob/master/doc/en/Access.md). То, что сейчас токены внутри реализованы через указатели, не значит, что токены - тоже указатели. Хотя имеют их черты. Просто привожу аналогию с умными указателями std чтобы сразу было примерно понятно, что это за штуковины :).


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 07, 2020, 11:50
не очевидно, нафига нужна эта библиотека.

Если вы прочитали всё документацию по ссылке и не нашли ничего полезного для себя, значит вам она не нужна. Что не отменяет факта её возможной полезности для других людей :).

конечно же я не читал всю документацию по ссылке.
поскольку не имею привычки тратить время не пойми на что.

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

вот например:
https://github.com/zeux/pugixml

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

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





Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 07, 2020, 11:59
конечно же я не читал всю документацию по ссылке.
поскольку не имею привычки тратить время не пойми на что.
...
в твоём случае оформление убогое.
я решил, что проще спросить у тебя на прямую:
зачем нужна эта вещь?
как её предполагается использовать?

Вам низачем и никак.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 07, 2020, 14:55
в твоём случае оформление убогое.
Как быстро срабатывает рефлекс "велик, костыль" :)

зачем нужна эта вещь?
как её предполагается использовать?
Пример: до боли простая задача/ситуевина
Код
C++ (Qt)
struct A {
...
B * data;
...
};  
"A" при этом НЕ владеет data, не отвечает ни за его создание ни удаление. Естественно экземпляр A получает по рогам при стороннем удалении data, и это надо мучительно отслеживать. Чтобы автоматом иметь валидность data приходится объявлять его weak, а сами данные создавать shared, никаких др стандартных средств нет. В итоге получается/навязывается липовый shared, ведь никакого совместного владения этими данными не планировалось. Задумка автора (насколько я понимаю) создать такую серию вумных указателей чтобы "легализовать" такое (и др) отношения использлвания.

Использование сторонней библиотеки всегда риск. Эту библиотеку я делаю для себя. Мне важно, чтобы я мог использовать такую функциональность в проектах, в которых я принимаю участие. И мне не жалко поделиться этими наработками с другими. Чтобы показать, что на С++ можно писать вот так, с меньшими страданиями :). Если на её основе сделают что-то покруче, так на здоровье. Будут ли ей пользоваться другие, меня уже меньше волнует. Как говорится: моё дело предложить :).
Конечно, имеете полное право. Все-таки с "функциональностью", на мой взгляд, слабкувато. Вы обеспечиваете лишь создание, копирование и удаление новых вумных указателей, и.. по сути все. Др словами Вы вставили каждую "сущность" в свою красивую рамочку. А установка и разрыв "отношений" по-прежнему всецело ручная работа, и ее немало.

Кстати за истекшее время я реализовал свою "фишку" (в первую очередь для решения проблемы выше). У меня получилась статУя вообще без всяких указателей/токенов. Т.е. для примера выше члена data просто нет. Вместо этого используется обращение к глобальной "таблице связей" между объектами. Однако это уже за рамками темы  :)


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 02:55
в твоём случае оформление убогое.
Как быстро срабатывает рефлекс "велик, костыль" :)

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

причем тут какие то рефлексы?

выше я приводил пример качественно оформленной библиотеки pugixml.
на самом деле подобных примеров масса.

вполне себе велосипед:
https://github.com/USCiLab/cereal





зачем нужна эта вещь?
как её предполагается использовать?
Пример: до боли простая задача/ситуевина
Код
C++ (Qt)
struct A {
...
B * data;
...
};  
"A" при этом НЕ владеет data, не отвечает ни за его создание ни удаление. Естественно экземпляр A получает по рогам при стороннем удалении data, и это надо мучительно отслеживать. Чтобы автоматом иметь валидность data приходится объявлять его weak, а сами данные создавать shared, никаких др стандартных средств нет. В итоге получается/навязывается липовый shared, ведь никакого совместного владения этими данными не планировалось. Задумка автора (насколько я понимаю) создать такую серию вумных указателей чтобы "легализовать" такое (и др) отношения использлвания.

1.
твой пример не иллюстриует как так получается,
что в какой то момент классу нужен доступ к ресурсу,
время жизни которого уже завершилось.

однако очевидно, что сама по себе такая ситуация - это какой то баг

2.
это - баг безотносительно к тому, использовал ты raw pointer, или связку shared/weak

допустим ты решил использовать невладеющий weak.
тогда у тебя на руках окажется невалидный weak, и как это тебе поможет?

тебе ресурс нужен, а его нет.
нужно звать программистов и чинить программу.

3.
ты написал про совместное владение так, словно думаешь,
будто бы область применения shared - когда предполагается неколько владельцев.

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

важно, что если есть несколько потребителей, значит нужен shared.
и он будет. в том или ином виде.

4.
я не понял, какое "такое" использование?
какая вообще проблема решается?






Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 08, 2020, 11:08
оформление убогое, потому что с таким оформлением
нужно обстоятельно вникать в документацию этой библиотеки,
просто для того, что бы понять, зачем она вообще нужна.

Вот уж действительно открытие, что техническую документацию нужно читать внимательно :). Что каждое слово там что-нибудь да значит, а не служит для описания красот и наполнения сцен, как в художественной. Например, про использование: если вам непонятна фраза "Using otn tokens is similar to using smart pointers from the C++ standard library." или вы не знаете, как пользоваться умными указателями стандартной библиотеки C++, то вам и токены вряд ли понадобятся.

Это первичная публикация бета-версии библиотеки. И прежде чем писать документацию для новичков, мне интересно мнение более опытных разработчиков.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 08, 2020, 13:03
ты написал про совместное владение так, словно думаешь,
будто бы область применения shared - когда предполагается неколько владельцев.

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

важно, что если есть несколько потребителей, значит нужен shared.
и он будет. в том или ином виде.
А разве при применении shared Вы как-то можете рулить такими сущностями как "владелец", "потребитель", "клиент" и что-то еще? Нет, просто "ввиду отсутствия таковых". Shared указатель - всегда один из владельцев, и данные живы пока есть хоть один shared - вот и вся любовь. Поэтому нет никакой разницы между "ты думаешь" и "на самом деле" :)

что в какой то момент классу нужен доступ к ресурсу,
время жизни которого уже завершилось.
Аналогия с "ресурсом" здесь неудачна/неуместна. Ресурс (напр icon) достаточно просто объявить shared, и все. Как уже подчеркивалось,  клиент (объект класса "A") НЕ владеет ссылкой (указателем на "B"), которая обычно активный объект (а вовсе не данные файла), может быть даже того же класса "A", и который может быть прибит хотя бы пользователем. Короче "один объект ссылается на другой" и никакими отношениями владения они в общем случае не связаны. Удивляет что Вы незнакомы с этой очень типовой ситуацией и считаете ее "каким-то багом".

допустим ты решил использовать невладеющий weak.
тогда у тебя на руках окажется невалидный weak, и как это тебе поможет?
Ну значит data не используется, ссылка разорвана. Это нормально, обычно "A" и конструируется с data = 0


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 13:27
Вот уж действительно открытие, что техническую документацию нужно читать внимательно :). Что каждое слово там что-нибудь да значит, а не служит для описания красот и наполнения сцен, как в художественной.

ты всерьёз думаешь, что кто-то придет на страничку с твоим проектом,
и увидев непойми что, станет тратить время на чтение непойми зачем?

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

титульный лист - это трейлер к голивудскому блокбастеру.
если трейлер не цепляет, люди не идут смотреть фильм.

про использование: если вам непонятна фраза "Using otn tokens is similar to using smart pointers from the C++ standard library." или вы не знаете, как пользоваться умными указателями стандартной библиотеки C++, то вам и токены вряд ли понадобятся.

вот ты пишешь:
"Using otn tokens is similar to using smart pointers from the C++ standard library."

пожалуй, это единственное предложение,
которое хоть как то проливает свет на предназначение библиотеки.

токены какие то.
это смарт-поинтеры что ли?
не проще было бы тогда так и писать: "библиотека смартпоинтеров с блэк-джеком и шлюхами"
сразу многие вопросы бы отпали.

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

где примеры использования?

примеры использование - это первое, что должен увидеть твой потенциальный пользователь,
сразу же после фразы: "предназначение библиотеки..."

другой важный маркеттинговый ход: локализация.
сейчас находишься в русскоязычном секторе.
здесь ты пытаешься пиарить своё детище.

где документация на русском языке?

Это первичная публикация бета-версии библиотеки. И прежде чем писать документацию для новичков, мне интересно мнение более опытных разработчиков.

моё мнение опытного разработчика:
оформи материал по человечески.

сейчас твоя библиотека выглядит как непонятно что, не понятно зачем.





Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 13:58
ты написал про совместное владение так, словно думаешь,
будто бы область применения shared - когда предполагается неколько владельцев.

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

важно, что если есть несколько потребителей, значит нужен shared.
и он будет. в том или ином виде.
А разве при применении shared Вы как-то можете рулить такими сущностями как "владелец", "потребитель", "клиент" и что-то еще? Нет, просто "ввиду отсутствия таковых". Shared указатель - всегда один из владельцев, и данные живы пока есть хоть один shared - вот и вся любовь. Поэтому нет никакой разницы между "ты думаешь" и "на самом деле" :)

разница есть.

ты же пишешь так, будто бы если владелец предполагается только один,
тогда shared уже не нужен.
это - не верно.

shared нужен когда у ресурса может быть несколько потребителей.
и не важно, сколько при этом будет владельцев.

Удивляет что Вы незнакомы с этой очень типовой ситуацией и считаете ее "каким-то багом".

может я не правильно понял, чего ты хочешь.
выше ты писал:

"A" при этом НЕ владеет data, не отвечает ни за его создание ни удаление. Естественно экземпляр A получает по рогам при стороннем удалении data, и это надо мучительно отслеживать.

ты считаешь что это нормально?
хотеть получить доступ к ресурсу, которого уже нет, и получить за это по рогам?
на мой взгляд, это противоречит здравому смыслу, не?

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

но в таких случаях это нужно заранее оговаривать, Бро!
и пояснять что делать, если ресурса нет в наличии.

например:
когда пользовать стучит на сервер, его запрос сначала передается специальному менеджеру.
менеджер проверяет есть ли в наличии юзерская сессия.
если нет - тогда запрашивает создание новой.
если есть - сразу отдаёт запрос юзера объекту его сессии.

для подобной ситуации weak подходит идеально.

резюмируя:
либо у тебя баг из-за невовремя протухающих ресурсов
либо это нормальная ситуация, и тогда weak - то, что доктор прописал.

вот только как это коррелирует с какими то непонятными "токенами"?
какую проблему класса "А" они решают?



Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 08, 2020, 15:12
титульный лист - это трейлер к голивудскому блокбастеру.
...
и вот здесь мы вполную подходим к главной изюменке любого годного маркеттинга:
...
Наверное "вплотную", "изюминке" и "маркетинга". Но, насколько я вижу, автор вовсе не стремится сделать это бестселлером, вещь вообще некоммерческая. Да, наверно стоит немного больше сказать "взагалi" и подсунуть примеры поближе - но это совсем не заслуживает потока "ниасиляторского" негодования :)

И кстати, Ваша критика была бы куда более уместной в отношении дуста. Не раз (и не два) тыкался там - и, да, "что-то есть", но ни толковой доки, ни примеров, ни хрена :'(

ты написал про совместное владение так, словно думаешь,
будто бы область применения shared - когда предполагается неколько владельцев.

на самом же деле, область применения shared - когда нужно расшаривать ресурс между несколькими потребителями.
количество владельцев при этом не суть важно.
Всякий shared - владелец, сделать его НЕ владельцем невозможно (как впрочем и заставить владеть монопольно). Если под "потребителем" имеется ввиду weak - надо так и говорить (а не наводить тень на плетень). Поэтому да, "область применения shared - когда предполагается несколько владельцев". Но это "по-хорошему", а сейчас его куда только ни суют за неимением лучшего.

например:
когда пользовать стучит на сервер, его запрос сначала передается специальному менеджеру.
менеджер проверяет есть ли в наличии юзерская сессия.
если нет - тогда запрашивает создание новой.
если есть - сразу отдаёт запрос юзера объекту его сессии.
Это момент "создания связи" где target (объект на который ссылаются) существовать обязан, поэтому проблем не возникает.

для подобной ситуации weak подходит идеально.
Нет, эта конструкция очень дырявая. Для того же простейшего примера. Во-первых, сделать "B" shared не так уж просто, ведь нужно чтобы юзер назначил эту связь, а значит "B" должен предъявляться в UI, иметь имя и.т.п. - какой уж тут shared. Значит придется шарить какие-то  внутренние данные "B", а тогда сразу огребем хотя бы при копировании "B". Чего и следовало ожидать: затыкать одну сущность другой плохо.

вот только как это коррелирует с какими то непонятными "токенами"?
какую проблему класса "А" они решают?
"If nothing could help - it's time to read doc" :)


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 08, 2020, 16:21
Всякий shared - владелец, сделать его НЕ владельцем невозможно (как впрочем и заставить владеть монопольно). Если под "потребителем" имеется ввиду weak - надо так и говорить (а не наводить тень на плетень). Поэтому да, "область применения shared - когда предполагается несколько владельцев". Но это "по-хорошему", а сейчас его куда только ни суют за неимением лучшего.

Я внезапно присоединюсь к _Bers (не думал что такой момент настанет) и попробую пояснить - автоматически "зануляющийся" указатель можно реализовать только связкой weak/shared по двум причинам. Первая в том, что weak требует своего отдельного счетчика ссылок, то есть это точно такой же refcount указатель как shared или COW классы. Даже QPointer реализован через QWeakPointer и QObject хранит внутри себя фейковую структуру SharedData от QSharedPointer (просто "основной" счетчик всегда -1). Вторая причина в том, что чтобы это потокобезопасно работало, надо уметь получать "сильную" ссылку, то есть shared_ptr. У weak_ptr нет метода .get() потому что он бесполезен! Просто проверка на отсутствие указателя условно полезна если вы хотите ничего не делать, или хотите делать, но указатель не нужен (сомнительная ситуация), если же надо что-то делать с указателем, то надо "стать владельцем" то есть вызвать .lock() (ака .toStrongRef())
Код:
if (weakPtr)
   foo(weakPtr.get()) // упс а тут уже nullptr
То есть условный QPointer применим только в однопоточном случае когда разраб "ниасилил" понять что там там где удаляется. Nuff said.


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 08, 2020, 16:48
Я внезапно присоединюсь к _Bers (не думал что такой момент настанет)
Скорее вы присоединились к здравому смыслу, потому что в том абзаце, на который вы отвечаете, написан фигня. :)
Igors так и не смог уяснить, что есть три понятия: ресурс, его владелец и пользователь ресурса, а умные указатели это средство управления этим хозяйством. Поэтому, глупо обсуждать эти механизмы в терминах "shared - владелец, а weak - нет", это разные уровни абстракции.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 08, 2020, 16:51
..автоматически "зануляющийся" указатель можно реализовать только связкой weak/shared по двум причинам.
В рамках "официальной доктрины" - да. Если хотим др ф-ционала - придется велосипедить, напр унаследоваться от shared и отрубить ему шаринг и.т.п.  Вот и получим нечто напоминающее один из классов предлагаемой либы

чтобы это потокобезопасно работало, надо уметь получать "сильную" ссылку, то есть shared_ptr.
Этот момент отнюдь не бесспорен/очевиден. "Продление жизни" может быть чревато самыми неприятными последствиями, напр если shared агрегирован, ведь для владельца все уже свершилось, он полагает что агрегированный уже сдох.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 16:55
Всякий shared - владелец, сделать его НЕ владельцем невозможно (как впрочем и заставить владеть монопольно). Если под "потребителем" имеется ввиду weak - надо так и говорить (а не наводить тень на плетень).

под "потребителем ресурса" я подразумею любого потребителя ресурса.

совершенно не важно, кем он является.
это может быть другой shared, weak, или обычный сырой указатель.

важно что он потребляет ресурс (хочет получать к нему доступ)

"область применения shared - когда предполагается несколько владельцев"

чувак не тупи.
вот с чего ты вообще это взял?

если у меня только 1 владелец, но множество потребителей,
мне ресурс шарить уже не нужно что ли?

как ты вообще себе представляешь доступ к одному ресурсу множества потребителей,
если при этом сам ресурс не расшарен????


Нет, эта конструкция очень дырявая. Для того же простейшего примера. Во-первых, сделать "B" shared не так уж просто, ведь нужно чтобы юзер назначил эту связь, а значит "B" должен предъявляться в UI, иметь имя и.т.п. - какой уж тут shared. Значит придется шарить какие-то  внутренние данные "B", а тогда сразу огребем хотя бы при копировании "B". Чего и следовало ожидать: затыкать одну сущность другой плохо.

я не понимаю, какое вообще отношение shared имеет к проблемам твоего UI ???

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

"If nothing could help - it's time to read doc" :)

ты даже не можешь сформулировать какая проблема решается.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 16:57
Скорее вы присоединились к здравому смыслу, потому что в том абзаце, на который вы отвечаете, написан фигня. :)

в каком таком "том" абзаце?

Поэтому, глупо обсуждать эти механизмы в терминах "shared - владелец, а weak - нет", это разные уровни абстракции.

я не понял, почему глупо?

shared - владелец.
weak -  не является владельцем ресурса.

и это - важный факты.

именно этим эти механизмы (отнюдь не абстрактные) и различаются.



Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 08, 2020, 17:06
в каком таком "том" абзаце?
На который отвечал Аварон. Очевидно же.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 17:08
напр унаследоваться от shared и отрубить ему шаринг

я правильно тебя понял:
ты хочешь унаследоваться от shared, что бы отрубить шаринг?

это типа как...

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

у тебя точно всё впорядке с логикой?




Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 08, 2020, 17:26
Чем спорить, кто shared, а кто ресурс, я бы предложил составить UML диаграмму классов. Но кто ж будет заниматься такой ерундой :).


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 17:28
Чем спорить, кто shared, а кто ресурс, я бы предложил составить UML диаграмму классов. Но кто ж будет заниматься такой ерундой :).

да не нужны никакие UML,
что бы понимать: shared - это механизм управления ресурсом, а не сам ресурс.



Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 08, 2020, 17:32
я правильно тебя понял:
ты хочешь унаследоваться от shared, что бы отрубить шаринг?
Совершенно правильно

это типа как...

унаследоваться от торговца, что бы отрубить ему торговлю?
унаследоваться от самолета, что бы отрубить ему возможность летать?
Да, именно так. Возможность летать мне не только не нужна, но даже вредит. Мне нужен только weak т.е. (хочу ползать :)) возможность наблюдать не сдох ли. Зияющая дыра в std: почему я не могу получить weak от "юника"?  Это ведь никак не менее usable.

у тебя точно всё впорядке с логикой?
Абсолютно (чувачок)  :)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 08, 2020, 17:37
да не нужны никакие UML,
что бы понимать: shared - это механизм управления ресурсом, а не сам ресурс.

Это даст общий знаменатель по терминам и семантике. Чтобы в одной сущности каждый не видел что-то своё (Слон и слепые мудрецы (http://www.iliko.ru/2017/05/16/%D1%81%D0%BB%D0%BE%D0%BD-%D0%B8-%D1%81%D0%BB%D0%B5%D0%BF%D1%8B%D0%B5-%D0%BC%D1%83%D0%B4%D1%80%D0%B5%D1%86%D1%8B/)).


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 08, 2020, 18:50

я правильно тебя понял:
ты хочешь унаследоваться от shared, что бы отрубить шаринг?
Совершенно правильно

это типа как...

унаследоваться от торговца, что бы отрубить ему торговлю?
унаследоваться от самолета, что бы отрубить ему возможность летать?
Да, именно так. Возможность летать мне не только не нужна, но даже вредит. Мне нужен только weak т.е. (хочу ползать :)) возможность наблюдать не сдох ли. Зияющая дыра в std: почему я не могу получить weak от "юника"?  Это ведь никак не менее usable.

ты никогда не думал о том, почему юник называется "юником" ?

никогда не думал о том, что если тебе не нужно летать,
тогда тебе просто не нужно использовать самолет?


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

у тебя точно всё впорядке с логикой?
Абсолютно (чувачок)  :)

заметно.








Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 08, 2020, 20:41
Этот момент отнюдь не бесспорен/очевиден. "Продление жизни" может быть чревато самыми неприятными последствиями, напр если shared агрегирован, ведь для владельца все уже свершилось, он полагает что агрегированный уже сдох.

Этот момент действительно неочевиден, но является единственным решением проблемы.
Где например используется QPointer в Qt? Ну какая-нибудь вьюха, наверное (код не смотрел) хранит QPointer на модель - модель удалили, вьюхе пофигу, она и так проверяет указатель на nullptr. Ровно тоже самое можно сделать на shared_ptr - нет никакой причины почему вьюхи не должны "шаредно" владеть моделью.
У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось (то есть в той же Qt QPointer юзается ровно по той причине что все виджеты в главном потоке и "продлять жизнь" не надо). Но ВНЕЗАПНО не все с++ погромисты пишут ГУИ тулкит и не у всех есть требование "только в главном потоке".


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 08, 2020, 20:48
Чем спорить, кто shared, а кто ресурс, я бы предложил составить UML диаграмму классов. Но кто ж будет заниматься такой ерундой :).

Да, UML рулит и механизма сделать агрегацию 1к1 в с++ нет. Точнее это будет 0/1 к 1 (указатель). Конечно, есть пресловутый not_null (а также мембер "по значению" для композиции) но это все не унифицированно/нестандартизировано.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 09, 2020, 08:40
никогда не думал о том,
что для того что бы ползать,
совсем необязательно наследоваться от самолета
и ломать наследнику крылья?
В текущей реализации std - увы, обязательно. Никаких др способов получить weak нет.

ты никогда не думал о том, почему юник называется "юником" ?
Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.

У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось
Не сказал бы что редки, QPointer - вещь вполне приличная, но она "интрузивна" (quard'ы хранятся в QObject), a std такого принципиально не признает.

нет никакой причины почему вьюхи не должны "шаредно" владеть моделью.
Хотя я тоже не могу сходу назвать причину, такой подход следует признать легкомысленным. Shared не то чтобы "редкий случай", но не такой уж и частый, не так уж много активных классов шарится. Думаю что лепить его типа "да вроде проходит" не надо.

Кстати - а почему внутри классов Qt вумные указатели юзаются редко, полно "голых"? Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 09, 2020, 09:16
Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.
Потому что weak на unique никому не нужен, у нас нет возможности продлить жизнь ресурса, которым управляет этот юник. Что должен делать weak на unique? Как он может помещать разрушить ресурс, которым управляет юник, из другого потока?
Вам Аварон об этом уже несколько раз написал.
Как только вы попробуете решить эту проблему юника, то у вас сразу получиться shared.


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 09, 2020, 09:28
У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось
Нет у него юзкейсов даже в Qt. :)
Его поведение со всеми его ограничениями легко реализуется например так:
Код
C++ (Qt)
void Bar::setResource( MyResource *res )
{
 m_res = res;
 connect( m_res, QObject::destroyed, [&]( QObject * ){ m_res = nullptr; } );
}
 

А дальше проверяй на не null.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 09, 2020, 10:33
Да, именно так. Возможность летать мне не только не нужна, но даже вредит. Мне нужен только weak т.е. (хочу ползать :)) возможность наблюдать не сдох ли. Зияющая дыра в std: почему я не могу получить weak от "юника"?  Это ведь никак не менее usable.

ты никогда не думал о том, почему юник называется "юником" ?

никогда не думал о том, что если тебе не нужно летать,
тогда тебе просто не нужно использовать самолет?

Хотите сказать, что не может существовать такая пара unique-weak, в которой weak становится expired, когда unique помирает?

Потому что weak на unique никому не нужен, у нас нет возможности продлить жизнь ресурса, которым управляет этот юник. Что должен делать weak на unique? Как он может помещать разрушить ресурс, которым управляет юник, из другого потока?
Вам Аварон об этом уже несколько раз написал.
Как только вы попробуете решить эту проблему юника, то у вас сразу получиться shared.

Продление жизни ресурса - это отдельный случай. То, что во время доступа через weak всё может грохнуться, если в это время в другом потоке unique удалит объект, не мешает иметь возможность expired для weak (Smart observers to use with unique_ptr (https://www.codeproject.com/Articles/1011134/Smart-observers-to-use-with-unique-ptr)). Равно как и weak для unique вообще, это вопрос терминологии. Голый указатель, полученный из unique_ptr::get(), вполне себе weak для unique, со своими особенностями.

Далее, можно разделять композитную агрегацию, когда объект-часть может входить в состав только одного объекта-целого одновременно, и временный доступ к этому объекту для чтения его данных/вызова методов, когда время его жизни будет продлено. Это опять же, вопрос терминологии.

Да, UML рулит и механизма сделать агрегацию 1к1 в с++ нет. Точнее это будет 0/1 к 1 (указатель). Конечно, есть пресловутый not_null (а также мембер "по значению" для композиции) но это все не унифицированно/нестандартизировано.

Вот я и попытался это классифицировать и унифицировать. Кстати, голый указатель C++ тоже распознается и участвует в библиотеке как токен, и можно получить его характеристики ;).


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 09, 2020, 10:38
Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.

И тем не менее это так https://lists.qt-project.org/pipermail/development/2020-January/038544.html


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 09, 2020, 17:35
В текущей реализации std - увы, обязательно. Никаких др способов получить weak нет.

смахивает на какой то бред.

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

ты никогда не думал о том, почему юник называется "юником" ?
Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.

в том то и дело, что противоречит.

ты вообще понимаешь, как работают с weak?

конкретно, ответь на вопрос:
почему напрямую через weak нельзя получить доступ к ресурсу,
а вместо этого приходится сначала расшаривать владельца?

Код:
#include <iostream>
#include <memory>

struct data
{
    int val = 333;
};

std::shared_ptr<data> holder = std::make_shared<data>();
 
int main()
{
    std::weak_ptr<data> weak = holder;
   
    // так нельзя
    // std::cout << "value = " << weak->val << '\n';
   
    // нужно сначала расшарить ресурс:
    std::shared_ptr<data> owner = weak.lock();     
    std::cout << "value = " << owner->val << '\n';
}

это связанно с тем, что поскольку weak не является владельцем,
то он не контролирует время жизни ресурса.
а значит, прямой доступ к ресурсу через него - всё равно что доступ через обычный голый указатель.
те же самые проблемы с безопасностью:
ресурс в любой момент может сдохнуть.
и потом ищи баги по всему коду.

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

однако в случае с unique_ptr, создание второго владельца противоречит самой идее существования юника.
хочешь рассшаривать - используй shared_ptr,
и не морочь голову ни себе, ни людям.


резюмируя:

если ты - наркоман, который не дружит с головой, тогда вот тебе твой weak специально для юника:

Код:
auto* weak1 = smart.get();
auto* weak2 = smart.get();
auto* weak3 = smart.get();

но если ты дружишь с головой, то ты понимаешь:
грамотный weak должен быть безопасным.
а безопасным он может только и только если гарантируется,
что ресурс не будет освобожден.

такие гарантии предоставляет shared_ptr

любая попытка сделать безопасный weak для юника приведет к тому,
что из юника получится shared



Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 09, 2020, 17:39
Хотите сказать, что не может существовать такая пара unique-weak, в которой weak становится expired, когда unique помирает?

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


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 10, 2020, 09:03
гарантировать безопасность
..
безопасность
..
безопасность
..
Используйте конкретный термин "not thread-safe" - ведь именно его Вы имели ввиду. Даже если бы это и было так, это не может быть основанием "невозможности", просто пишем что данный класс/фича "not thread-safe", и спокойно ее юзаем. Да, если дело дойдет до multi-threading - придется прилагать усилия, лочить и.т.п. Но это обычная работа которую приходится делать во многих случаях, нередко и с "продленным" weak.

хочешь рассшаривать - используй shared_ptr,
и не морочь голову ни себе, ни людям.
Эту песню я слышал много раз.
Код:
Голые указатели = плохо. Давайте сделаем все указатели вумными! И будет счастье! 
Ну а поскольку возможности юника на практическом нуле - остается делать все shared. Вас не смущает что это чисто ход мысли начинающего? Что давать такие советы не требует никакого (ну совсем никакого) ума? Вы сами-то пробовали так делать? И что, хорошо получилось? Может лучше поменять взад на голые?  :)

Да, и чисто технически "продлить юник" несложно. Причем используя совершенно легальные средства предоставляемые std. Несколькими постами выше ViTech кинул ссылочку, интересно - почитаете.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 09:58
хочу сказать, что невозможно организовать безопасный доступ к ресурсу юника через weak,
не сделав при этом сам юник шаредом.

А для однопоточного случая?

Раз уж никто не хочет рисовать UML диаграммы, вот одна такая (https://gitlab.com/UnifiedPointers/Example/Car/-/blob/master/doc/ru/Readme.md), с постановкой задачи. Какие будут предложения по её решению на текущем C++ с его стандартной библиотекой?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 11:35
А для однопоточного случая?

не плоди сущности без необходимости.

Код:
auto* weak = unique.get();


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 11:42
не плоди сущности без необходимости.

Код:
auto* weak = unique.get();

И где тут "weak становится expired, когда unique помирает"?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 11:51
И где тут "weak становится expired, когда unique помирает"?

зачем он нужен?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 11:59
Используйте конкретный термин "not thread-safe" - ведь именно его Вы имели ввиду.
Даже если бы это и было так, это не может быть основанием "невозможности", просто пишем что данный класс/фича "not thread-safe",
и спокойно ее юзаем.
Да, если дело дойдет до multi-threading - придется прилагать усилия, лочить и.т.п.
Но это обычная работа которую приходится делать во многих случаях, нередко и с "продленным" weak.

для однопоточного случая используй обычный голый указатель - никакой разницы.

Эту песню я слышал много раз.
Голые указатели = плохо. Давайте сделаем все указатели вумными! И будет счастье!
Ну а поскольку возможности юника на практическом нуле - остается делать все shared.
Вас не смущает что это чисто ход мысли начинающего?
Что давать такие советы не требует никакого (ну совсем никакого) ума?
Вы сами-то пробовали так делать? И что, хорошо получилось?
Может лучше поменять взад на голые?  :)

ты вообще понимаешь зачем нужны умные указатели?
если умный указатель не даёт никаких приимуществ по сравнению с обычным сырым указателем,
то нахера он нужен?

Да, и чисто технически "продлить юник" несложно. Причем используя совершенно легальные средства предоставляемые std.
Несколькими постами выше ViTech кинул ссылочку, интересно - почитаете.

остановок "туда" и "здеся" не существует.
существуют только конкретные остановки.
и конкретные ссылки.






Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 12:02
И где тут "weak становится expired, когда unique помирает"?

зачем он нужен?

Быстро же вы ответы изменяете )).

Я так понял: "зачем ... нужен?" - это ваш коронный вопрос. А зачем нужен std::weak_ptr::expired()?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 12:19
Быстро же вы ответы изменяете )).

я пришел к выводу, что для std::unique_ptr нельзя без приседаний получить pointer&
а значит для поддержки expired потребуется совершить некоторые телодвижения.

сразу закономерный вопрос: нафига это нужно?

Я так понял: "зачем ... нужен?" - это ваш коронный вопрос. А зачем нужен std::weak_ptr::expired()?

очень правильный вопрос.
дело в том, что std::weak_ptr::expired() - это очень вредный метод

это - зло, ставшее причиной множества багов.

у этого зла есть имя: "функционал, который даёт ложное чувство безопасности"

я сам лично неоднократно встречал такой код:

Код:
if(!weak.expired())
    weak.lock()->work();  // <--- баг


weak не контролирует время жизни ресурса.
то, что он ещё не протух, не значит, что не протухнет в след. мгновение.


правильный код должен быть:

Код:
if(!weak.expired())
{
    auto shared = weak.lock();
    if(shared)
       shared ->work();  // <--- ok
}

только шаред может дать гарантию.

так зачем же все таки нужен метод weak_ptr::expired() ?
собака зарыта в методе lock.
lock лочит разделяемые между потоками данные shared.
что как известно - не бесплатно.

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

Код:
if(!weak.expired())  // <--- быстрая проверка
{
    auto shared = weak.lock();  // <--- медленный лок

    if(shared) // <--- окончательная проверка
       shared ->work();  // <--- можно работать
}






Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 12:29
weak не контролирует время жизни ресурса.
то, что он ещё не протух, не значит, что не протухнет в след. мгновение.

Зато если он протух, это признак того, что объект помер и можно выполнить соответствующие похоронные действия. Или ничего не делать. Вот и весь функционал expired, не более.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 12:40
weak не контролирует время жизни ресурса.
то, что он ещё не протух, не значит, что не протухнет в след. мгновение.

Зато если он протух, это признак того, что объект помер и можно выполнить соответствующие похоронные действия. Или ничего не делать. Вот и весь функционал expired, не более.

его завезли только ради возможности не лочить шаред зазря.

если бы получение шареда было быстрым,
тогда expired бы сейчас не существовало.



Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 10, 2020, 12:41
Зато если он протух, это признак того, что объект помер и можно выполнить соответствующие похоронные действия. Или ничего не делать. Вот и весь функционал expired, не более.
Ну так в однопоточном режиме expired юника как раз:
Код
C++ (Qt)
if( (auto p = unique_ptr.get()) )
{
 p->do();
 p->bar();
}
 
Пока вы контролируете поток исполнения вы видите в каком месте этот юник может умереть. И если такой момент присутствует, то просто проверяете валидность указателя после него еще раз.
В однопоточной среде с этим нет никаких проблем.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 12:50
Зато если он протух, это признак того, что объект помер и можно выполнить соответствующие похоронные действия. Или ничего не делать. Вот и весь функционал expired, не более.
Ну так в однопоточном режиме expired юника как раз:
Код
C++ (Qt)
if( (auto p = unique_ptr.get()) )
{
 p->do();
 p->bar();
}
 
Пока вы контролируете поток исполнения вы видите в каком месте этот юник может умереть. И если такой момент присутствует, то просто проверяете валидность указателя после него еще раз.
В однопоточной среде с этим нет никаких проблем.



хочется держать сам юник в одном месте,
а вики на него - в 10 других местах.

и вот в этих местах нужно знать: протух ресурс, или нет.


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

если же сам юник протухнет,
считай что его вики в виде сырых указателей так же протухли

Код:
auto*& example::get_weak()
{
    return &owner; // std::unique_ptr<some>
}









Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 13:00
его завезли только ради возможности не лочить шаред зазря.

если бы получение шареда было быстрым,
тогда expired бы сейчас не существовало.

Когда шаред залочить не получается, это тоже признак того, что объект помер, и weak находится в состоянии "expired". Т.е. условно проверка weak на bool в if() направит в ветку else. Вот эта функциональность и нужна: узнать, что объект помер.

Ну так в однопоточном режиме expired юника как раз:
Код
C++ (Qt)
if( (auto p = unique_ptr.get()) )
{
 p->do();
 p->bar();
}
 
Пока вы контролируете поток исполнения вы видите в каком месте этот юник может умереть. И если такой момент присутствует, то просто проверяете валидность указателя после него еще раз.
В однопоточной среде с этим нет никаких проблем.

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


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 10, 2020, 13:01
хочется держать сам юник в одном месте,
а вики на него - в 10 других местах.
А тут возникает следующая проблема. Мы держим сырой указатель на юник, а в процессе выполнения разрушается объект, который хранил этот юник и указатель становится не валидным. :)

Придется добавлять свой умный указатель и шарить юник. Так зачем шарить юник если есть shared. :)


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 10, 2020, 13:03
А если объекты и связи между ними создаются и удаляются динамически? По-моему, проблемы могут возникнуть.
Ну так в однопоточной среде можно проверить еще раз:
Код
C++ (Qt)
if( (auto p = unique_ptr.get()) )
{
 p->do();
 p->bar();
}
 
xrenEgoZnaet();
 
// Проверяем повторно
if( (auto p = unique_ptr.get()) )
{
 p->foo();
 p->bla();
}
 


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 13:09
хочется держать сам юник в одном месте,
а вики на него - в 10 других местах.
А тут возникает следующая проблема. Мы держим сырой указатель на юник, а в процессе выполнения разрушается объект, который хранил этот юник и указатель становится не валидным. :)

Придется добавлять свой умный указатель и шарить юник. Так зачем шарить юник если есть shared. :)

ну вот они не хотят ничего не шарить.

а хотят просто получить вик с юника,
который им скажет: протух ресурс или нет?

Код:
if(weak)
    weak->work();  // то, что это не безопасно, их не смущает.





Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 13:10
Ну так в однопоточной среде можно проверить еще раз:
...

Вот пример задачи Car (https://gitlab.com/UnifiedPointers/Example/Car/-/blob/master/doc/ru/Readme.md). Даже для однопоточного варианта, какое решение предложите?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 13:14
Ну так в однопоточной среде можно проверить еще раз:
...

Вот пример задачи Car (https://gitlab.com/UnifiedPointers/Example/Car/-/blob/master/doc/ru/Readme.md). Даже для однопоточного варианта, какое решение предложите?

формулировка задачи: "один движок - много мониторов"
"один ресурс - множество потребителей" - привет, shared!





Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 13:19
формулировка задачи: "один движок - много мониторов"
"один ресурс - множество потребителей" - привет, shared!

Я и не сомневался. Но там и другие требования есть. Например:
Один Engine можно установить только в один Car. Установка одного и того же Engine в несколько разных Car недопустима.

Как его соблюдать предлагаете?


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 10, 2020, 13:20
Вот пример задачи Car (https://gitlab.com/UnifiedPointers/Example/Car/-/blob/master/doc/ru/Readme.md). Даже для однопоточного варианта, какое решение предложите?
То что в стандартной библиотеке нет указателей с необходимыми свойствами я не спорю. :)
Я подумаю еще над задачей, но на первый взгляд я бы использовал shared с какой нибудь проверкой на количество в рантайм.
Но я подумаю.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 13:32
Я и не сомневался. Но там и другие требования есть. Например:
Один Engine можно установить только в один Car. Установка одного и того же Engine в несколько разных Car недопустима.

Как его соблюдать предлагаете?

Код:
class BMW: public Car
{
    BMW() { this->setEngine<BMW_Engine>(); }
};

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

это называется "инкапсуляция".





Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 13:35
Код:
class BMW: public Car
{
    BMW() { this->setEngine<BMW_Engine>(); }
};

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

это называется "инкапсуляция".

Двигатель в BMW заменить на другой нельзя? Это как называется? :)

И здесь this->setEngine<BMW_Engine>() откуда двигатель берётся?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 14:20
Двигатель в BMW заменить на другой нельзя? Это как называется? :)

я называю это "практичность"
нех лазить куда не надо.

хочешь двигатель от мерседеса - возьми мерседес.


ежели очень надо отхватить гемморой  сделать иньекцию зависимостей,
тогда вытащи в паблик метод setEngine<type of engine>(params...);

И здесь this->setEngine<BMW_Engine>() откуда двигатель берётся?

по месту (emplace) конструируется.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 14:34
я называю это "практичность"
нех лазить куда не надо.

хочешь двигатель от мерседеса - возьми мерседес.

А если просто двигатель помощнее нужно установить взамен существующего? Или он сломался. Менять авто целиком? Очень практично :).

по месту (emplace) конструируется.

Это простой пример с минимумом классов, чтобы не засорять его несущественными для него деталями. В реальном приложении Car будет знать только об интерфейсе Engine, и функциональность по созданию двигателя в авто может быть избыточной или вообще невозможной.

Вы начинаете какие-то свои задачи придумывать и их решать. Вот эту конкретную с указанными требованиями можете решить? Впрочем, можете опять спросить: "А зачем это всё нужно?" :).


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 15:12
А если просто двигатель помощнее нужно установить взамен существующего? Или он сломался. Менять авто целиком? Очень практично :).

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

сломался двигатель?
ну так почини его.

менять сам объект для этого не нужно.

Код:
void clear_input()
{
    std::wcin.clear(),
    std::wcin.ignore(std::numeric_limits<std::streamsize>::max(), L'\n');

    assert(std::wcin);  // <--- и о боже! наш двигатель снова работает!
}

на практике, от иньекций зависимостей больше головняков, чем пользы.


В реальном приложении Car будет знать только об интерфейсе Engine,
и функциональность по созданию двигателя в авто может быть избыточной или вообще невозможной.

а! я понял.
ты просто не понимаешь, как работает emplace.
если хочешь, я тебе подробно расспишу как правильно готовят это блюдо.

если вкратце,
Car не нужно ничего знать ни о каких наследниках Engine
это никак не мешает сконструировать двигатель по месту.

Вы начинаете какие-то свои задачи придумывать и их решать. Вот эту конкретную с указанными требованиями можете решить? Впрочем, можете опять спросить: "А зачем это всё нужно?" :).

вот это поворот.

ты хотел машинку с кучкой мониторов, и 1 нерасшариваемым двигателем.
ты её получил.

ну и чего тебе не нравится?


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 15:35
Вы начинаете какие-то свои задачи придумывать и их решать. Вот эту конкретную с указанными требованиями можете решить? Впрочем, можете опять спросить: "А зачем это всё нужно?" :).

вот это поворот.

ты хотел машинку с кучкой мониторов, и 1 нерасшариваемым двигателем.
ты её получил.

ну и чего тебе не нравится?

...

Ну и зачем потёрли свою сентенцию о том, что мои токены оказались на хрен не нужны? :) Так я вам об этом сразу сказал (http://www.prog.org.ru/index.php?topic=32613.msg241093#msg241093). Решайте свои задачи, у меня другие.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 15:43
Ну и зачем потёрли свою сентенцию о том, что мои токены оказались на хрен не нужны? :) Так я вам об этом сразу сказал (http://www.prog.org.ru/index.php?topic=32613.msg241093#msg241093). Решайте свои задачи, у меня другие.

решил, что излишняя эмоциональность не нужна.

у меня такое впечатление сложилось,
что ты занимаешься не задачами, а философией.



Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 15:54
у меня такое впечатление сложилось,
что ты занимаешься не задачами, а философией.

Философией тоже кто-то заниматься должен. Вот есть уже два варианта решения задачи. Я вашим пользоваться точно не буду. А вы моим. Другие участники форума сами для себя решат, какое решение им ближе, и нужны ли им такие токены. :)


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 16:06
Я вашим пользоваться точно не буду

если ты про emplace, то это не мой способ.
эта техника сегодня применяется повсеместно (http://www.cplusplus.com/reference/vector/vector/emplace_back/).



Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 16:17
если ты про emplace, то это не мой способ.
эта техника сегодня применяется повсеместно (http://www.cplusplus.com/reference/vector/vector/emplace_back/).

Типа такого (https://gitlab.com/CppObjectTokens/Module/Library/CppOtl/-/blob/master/doc/en/Construction.md#itself_type-constructor)?


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 10, 2020, 16:37
если ты про emplace, то это не мой способ.
эта техника сегодня применяется повсеместно (http://www.cplusplus.com/reference/vector/vector/emplace_back/).

Типа такого (https://gitlab.com/CppObjectTokens/Module/Library/CppOtl/-/blob/master/doc/en/Construction.md#itself_type-constructor)?


ага


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 16:53
Типа такого (https://gitlab.com/CppObjectTokens/Module/Library/CppOtl/-/blob/master/doc/en/Construction.md#itself_type-constructor)?
ага

Тогда в конструкторе SomeCar (даже когда он в cpp файле находится) должен быть доступен конкретный тип SomeEngine. Такая зависимость может быть нежелательна или невозможна.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 10, 2020, 17:37
Ну ладно, реализовал Car (аттач) как я понял задачу. Никакого применения вумным указателям я тут не вижу. Воткнул один юник, но чисто для понту, и без него можно спокойно обойтись.

Замечу что копирование таких зависимостей проблематично: если копируется только car - все ясно, мониторы копироваться не должны. А если копируются и мониторы? Др момент: избежать вектора мониторов в практической задаче вряд ли удастся - наблюдающий обязан среагировать на смену наблюдаемого.



Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 10, 2020, 18:02
Статический мьютекс это прекрасно =)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 10, 2020, 19:38
Ну ладно, реализовал Car (аттач) как я понял задачу. Никакого применения вумным указателям я тут не вижу. Воткнул один юник, но чисто для понту, и без него можно спокойно обойтись.

Что ж... пусть это будет третий вариант. Может кто-то возьмёт его на вооружение :).

Согласно UML диаграмме, у Engine нет ссылок/указателей на Car и Monitor. Такие дела.

Замечу что копирование таких зависимостей проблематично: если копируется только car - все ясно, мониторы копироваться не должны. А если копируются и мониторы? Др момент: избежать вектора мониторов в практической задаче вряд ли удастся - наблюдающий обязан среагировать на смену наблюдаемого.

Копирование - это другая история и не нужно, этот пример про целостность связей.


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 11, 2020, 08:47
Ух! Стоило отвлечся и понаписали))).
Внесу свой вклад в обсуждение (чтобы еще больше всех запутать).

Объектно-ориентированная модель является первичной по отношению к объектно ориентированной программе.
При этом одну и ту же модель можно реализовать совершенно разными способами.

(http://www.prog.org.ru/index.php?action=dlattach;topic=32613.0;attach=9771;image)

Рассмотрим модель, представленную на рисунке. На ней представлен ресурс, владелец ресурса и пользователи ресурса.
Владелец композитно владеет ресурсом в соотношении 1 владелец - 1 ресурс.
Пользователи имеют только ассоциативную связь с ресурсом в соотношении много пользователей - 1 ресурс.
Существует большое количество разнообразных способов реализации данной модели, каждая из которых обладает определенными свойствами.

1. Простейший способ реализации

Код
C++ (Qt)
struct Owner
{
   Resource m_resource;
};
 

Распределение ресурса по месту владельца.
Нельзя извлечь ресурс и сломать ассоциативные связи с ним.
Гарантированное отношение 1 владелец - 1 ресурс.
Потоко небезопасный доступ к ресурсу.

Код
C++ (Qt)
struct User
{
   Resource & m_resource;
};
 

Неизменяемая ассоциация с ресурсом.
Отсутствие контроля корректности ассоциативной связи с ресурсом.
Гарантированное отношение много пользователей - 1 ресурс.
Потоко небезопасный доступ к ресурсу.

Возможен такой вариант

Код
C++ (Qt)
struct User
{
   ::std::reference_wrapper< Resource > m_resource;
};
 

Изменяемая ассоциация с ресурсом.
Отсутствие контроля корректности ассоциативной связи с ресурсом.
Гарантированное отношение много пользователей - 1 ресурс.
Потоко небезопасный доступ к ресурсу.

2. Может быть выбран способ реализации через raw указатели, но тогда программа усложняется

Код
C++ (Qt)
struct Owner
{
   Resource * m_resource = nullptr;
 
   Owner () : m_resource( new Resource ) {}
   ~Owner () { delete m_resource; }
   Owner ( Owner && other ) { ::std::swap( m_resource, other.m_resource ); }
   Owner ( const Owner & other ) : m_resource( new Resource( *other.m_resource ) ) {}
};
 

Распределение ресурса в куче.
Можно сломать ассоциативные связи с ресурсом.
Контроль отношения 1 владелец - 1 ресурс лежит на программисте.
Потоко небезопасный доступ к ресурсу.

Код
C++ (Qt)
struct User
{
   Resource * m_resource;
   User ( Resource & resource ) : m_resource( ::std::addressof( resource ) );
};
 

Изменяемая ассоциация с ресурсом.
Отсутствие контроля доступа к ресурсу.
Контроль отношения много пользователей - 1 ресурс лежит на программисте.
Потоко небезопасный доступ к ресурсу.

3. Реализация через unique_ptr

Код
C++ (Qt)
struct Owner
{
   ::std::unique_ptr< Resource > m_resource;
 
   Owner () : m_resource( ::std::make_unique< Resource >() ) {}
   Owner ( const Owner & other ) : m_resource( ::std::make_unique< Resource >( *other.m_resource ) ) {}
};
 

Распределение ресурса в куче.
Можно сломать ассоциативные связи с ресурсом.
Контроль отношения 1 владелец - 1 ресурс лежит на программисте.
Потоко небезопасный доступ к ресурсу.

Подойдет любая реализация User из вариатнов выше.

4. Реализация через shared_ptr

Код
C++ (Qt)
struct Owner
{
   ::std::shared_ptr< Resource > m_resource;
 
   Owner () : shared_ptr( ::std::make_shared< Resource >() ) {}
   Owner ( Owner && other ) { ::std::swap( m_resource, other.m_resource ); }
   Owner ( const Owner & other ) : m_resource( ::std::make_unique< Resource >( *other.m_resource ) ) {}
};
 

Распределение ресурса в куче.
Можно сломать ассоциативные связи с ресурсом.
Контроль отношения 1 владелец - 1 ресурс лежит на программисте.
Потоко небезопасный доступ к ресурсу.

Такая реализация прямо не соответствует композитной связи из модели и требует аккуратного использования.
Сложно гарантировать (тем более, когда разработчиков много), что случайно не возникнет совместного владения ресурсом.
Но именно такая реализация позволяет контролировать доступ к ресурсу.

Кроме реализация User из вариатнов выше, может быть такая

Код
C++ (Qt)
struct User
{
   ::std::weak_ptr< Resource > m_resource;
   User ( ::std::shared_ptr< Resource > resource ) : m_resource( resource );
};
 

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

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

Контроль доступа к ресурсу может осуществлен и другими способами, не только связкой shared/weak, например, с помощью mutex, или учетом всех ассоциаций, или совместным владением raw указателя на ресурс, или др. При этом можно контролировать и другие свойства, такие как потоко безопасность, ленивые вычисления и т.п.


Всё что понаписано выше - это примеры того, как одна и та же модель реализуется с помощью разных примитивов языка C++ и библиотеки std. Для контроля разных дополнительных свойств, необходимых в конкретной программе, этих примитивов не достаточно, и требуется дополнительный контроль корректности использования ассоциативных связей со стороны программиста.

C++ Object Token Library предоставляет примитивы, которые контроль корректности использования ассоциативных связей, перекладывают на компилятор. Некий синтаксический сахар, чтобы случайно не выстрелить себе в ногу).

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


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 11, 2020, 09:32
Статический мьютекс это прекрасно =)
Могли бы указать на содержательные ошибки (напр в Engine::~Engine). Одни финтифлюшки на уме.

Что ж... пусть это будет третий вариант. Может кто-то возьмёт его на вооружение :).
Не видел ни первого ни второго  :)

Согласно UML диаграмме, у Engine нет ссылок/указателей на Car и Monitor. Такие дела.
Значит неверна диаграмма. Engine должна знать куда она вмонтирована. Иначе потом не протолкнуться

Копирование - это другая история и не нужно, этот пример про целостность связей.
С Вашей либой я знаком очень поверхностно, поэтому поправьте если дальше не так. Как я понял, задумка в том чтобы вместо голого Monitor::mEngine иметь нечто получше, что хотя бы обеспечит валидность этого указателя (теперь уж наверно "токена"). Тут 2 момента

1) Чтобы получить это "получше" придется объявлять/создавать указатель на Engine чем-то "эдаким" (так или иначе а счетчик ссылок куда-то воткнуть надо). А дальше посыпется все по цепочке домино - ВСЕ указатели должны быть Ваши, потенциальный юзер должен ВСЕЦЕЛО принять Вашу идеологию указателей/токенов. Такое предложение просто неприлично (это еще очень мягко говоря).

2) Хорошо, допустим Ваша концепция даже принята, что несчастная жертва с этого имеет? Богатый набор указателей с человеческой валидностью (что по-хорошему должно быть в std). Согласен. Что еще? Да НИЧЕГО. Как только абстрактный пример Car-Engine-Monitor станет реальным - придется обеспечивать и копирование, и синхронизацию - то что я написал. И разве Ваша либа в этом как-то поможет? Не вижу как. Тогда "за что боролись"? Где "выйгрышь"?

Есть ли другие способы? Думаю что есть. См напр Engine::mMonitors и Monitor::Engine. Эти голые указатели изрядно засоряют рабочие классы. Как избавиться от них, при этом сохранив public методы типа AddMonitor? По-моему это неплохо обобщается, и, не менее важно, не накладывает на юзверя никаких обязательств. Но... Вы ведь это слушать все равно не будете, да и "пиар своего детища" в мои планы не входит  :)






Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 11, 2020, 10:09
Что ж... пусть это будет третий вариант. Может кто-то возьмёт его на вооружение :).
Не видел ни первого ни второго  :)

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

Согласно UML диаграмме, у Engine нет ссылок/указателей на Car и Monitor. Такие дела.
Значит неверна диаграмма. ...

Точнее и не скажешь :D.

С Вашей либой я знаком очень поверхностно, поэтому поправьте если дальше не так. Как я понял, задумка в том чтобы вместо голого Monitor::mEngine иметь нечто получше, что хотя бы обеспечит валидность этого указателя (теперь уж наверно "токена"). Тут 2 момента

1) Чтобы получить это "получше" придется объявлять/создавать указатель на Engine чем-то "эдаким" (так или иначе а счетчик ссылок куда-то воткнуть надо). А дальше посыпется все по цепочке домино - ВСЕ указатели должны быть Ваши, потенциальный юзер должен ВСЕЦЕЛО принять Вашу идеологию указателей/токенов. Такое предложение просто неприлично (это еще очень мягко говоря).

2) Хорошо, допустим Ваша концепция даже принята, что несчастная жертва с этого имеет? Богатый набор указателей с человеческой валидностью (что по-хорошему должно быть в std). Согласен. Что еще? Да НИЧЕГО. Как только абстрактный пример Car-Engine-Monitor станет реальным - придется обеспечивать и копирование, и синхронизацию - то что я написал. И разве Ваша либа в этом как-то поможет? Не вижу как. Тогда "за что боролись"? Где "выйгрышь"?

Есть ли другие способы? Думаю что есть. См напр Engine::mMonitors и Monitor::Engine. Эти голые указатели изрядно засоряют рабочие классы. Как избавиться от них, при этом сохранив public методы типа AddMonitor? По-моему это неплохо обобщается, и, не менее важно, не накладывает на юзверя никаких обязательств. Но... Вы ведь это слушать все равно не будете, да и "пиар своего детища" в мои планы не входит  :)

Я же выше уже говорил, моё дело предложить :). А дальше пусть каждый для себя выбирает, какой вариант ему больше подходит. Благо их количество постепенно увеличивается и есть из чего выбирать :).


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 11, 2020, 10:35
Ну первый увидеть немудрено,
На странице "UML" есть ссылка "Examples", тыкал туда, но кода не увидел. Это опять надо лазить (не стал), и это (ненужно) напрягает. Как-то у Вас с саморекламой плоховато.

Я же выше уже говорил, моё дело предложить
Согласен, имеете право

Тут мелькнул интересный момент, но, как всегда, растворился в дальнейшей перебранке типа "ага/угу". Утверждалось (неоднократно) что "юник" один - и только один, поэтому, дескать, никакое продление жизни для него невозможно, т.к. он немедленно станет shared, а так низзя

Вот пример из букваря
Код
C++ (Qt)
static void doDeleteLater(MyObject *obj)
{
   obj->deleteLater();
}
 
Ну а если не deleteLater а напр какой-нибудь push_back который создаст из raw указателя shared? Как видим, Qt/std против этого совсем не возражают. Да, юник один, и он отстрелялся (его delete свершилось). Но убивать сами данные никто не заставляет.
Да
Цитировать
Была докторская - стала любительская
Требуется просто "не обе вместе/одновременно". А для пресловутого продления и shared не требуется


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 11, 2020, 10:36
C++ Object Token Library предоставляет примитивы, которые контроль корректности использования ассоциативных связей, перекладывают на компилятор. Некий синтаксический сахар, чтобы случайно не выстрелить себе в ногу).

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

Именно так. Сейчас токены - это обёртки над голыми указателями и умными указателями из std (внутри которых всё равно голые указатели). Можно только на этих голых указателях писать, Igors пример привёл :). Можно на Си писать, можно на ассемблере. Вопрос в усилиях, которые должен приложить разработчик, удобстве выражения мыслей, наглядности, корректности и безопасности кода.

Кому-то не хватало возможностей голых указателей - он придумал умные указатели. Мне не хватало возможностей умных указателей std - так появились токены объектов. С их помощью можно писать выразительнее и безопаснее, больше работы переложить на компилятор. Хорошо бы, чтоб при этом и статический анализ развивался, чтобы больше ошибок на этапе компиляции выявлялось.

Ещё попытался внести порядок в терминологию и классификацию. А то все говорят "владение", "владелец", "шаред" и т.п., но кто даст точные определения этим терминам, тому буду благодарен :).


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 11, 2020, 10:49
Можно только на этих голых указателях писать, Igors пример привёл :). Можно на Си писать, можно на ассемблере. Вопрос в усилиях, которые должен приложить разработчик, удобстве выражения мыслей, наглядности, корректности и безопасности кода.
Я бы это сформулировал иначе

Вопрос сколько времени и сил мне нужно затратить на освоение нового инструмента, сколько существующего кода мне придется переделать (со всеми вытекающими), и что я с того нового инструмента получу

И, на мой взгляд, тут баланс явно не в Вашу пользу


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 11, 2020, 11:06
На странице "UML" есть ссылка "Examples", тыкал туда, но кода не увидел. Это опять надо лазить (не стал), и это (ненужно) напрягает. Как-то у Вас с саморекламой плоховато.

Да, претензия принимается. Для старой библиотеки скрыл некоторые репозитории, ссылки побились, что внесло некоторую неопределённость. Страница с UML находится в репозитории Example/Car (https://gitlab.com/UnifiedPointers/Example/Car), её путь отображается в верхней части страницы. Соответственно, код здесь (https://gitlab.com/UnifiedPointers/Example/Car/-/blob/master/src/main.cpp).

Тот же пример в актуальной библиотеке: Car (https://gitlab.com/CppObjectTokens/Module/Example/Car).

Можно только на этих голых указателях писать, Igors пример привёл :). Можно на Си писать, можно на ассемблере. Вопрос в усилиях, которые должен приложить разработчик, удобстве выражения мыслей, наглядности, корректности и безопасности кода.
Я бы это сформулировал иначе

Вопрос сколько времени и сил мне нужно затратить на освоение нового инструмента, сколько существующего кода мне придется переделать (со всеми вытекающими), и что я с того нового инструмента получу

И, на мой взгляд, тут баланс явно не в Вашу пользу

С этим я спорить абсолютно не буду, в Вашем случае всё именно так, как Вы описали :).


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 11, 2020, 12:35
Ух! Стоило отвлечся и понаписали))).
Внесу свой вклад в обсуждение (чтобы еще больше всех запутать).

Объектно-ориентированная модель является первичной по отношению к объектно ориентированной программе.
При этом одну и ту же модель можно реализовать совершенно разными способами.
...

Отличный разбор полётов :).

Выше уже писал, что в случае с inplace (по месту владельца) смущают ситуации со сменой/перемещением ресурса. В случае с кучей, User связан с "отдельным ресурсом", в случае inplace, User связан с "ресурсом, который связан с Owner", как-то это не consistent :). Как бы тут гармонию навести?

Пример:
Код
C++ (Qt)
#include <memory>
#include <string>
#include <iostream>
 
using namespace std;
 
template <class T>
using heap_unique = unique_ptr<T>;
 
template <class T>
using inplace_unique = T;
 
template <class T>
using weak = T *;
 
using Resource = string;
 
int main()
{
   cout << "----- heap -----" << endl;
   heap_unique<Resource> heap_owner_1 = make_unique<Resource>("heap_resource_1");
   weak<Resource>        heap_weak{heap_owner_1.get()};
   cout << "heap_owner_1: " << *heap_owner_1 << endl;
   cout << "heap_weak   : " << *heap_weak << endl;
   cout << "moving..." << endl;
   heap_unique<Resource> heap_owner_2 = std::move(heap_owner_1);
   heap_owner_1 = make_unique<Resource>("heap_resource_2");
   cout << "heap_owner_1: " << *heap_owner_1 << endl;
   cout << "heap_owner_2: " << *heap_owner_2 << endl;
   cout << "heap_weak   : " << *heap_weak << endl;
   cout << endl;
 
   cout << "----- inplace -----" << endl;
   inplace_unique<Resource> inplace_owner_1 = "inplace_resource_1";
   weak<Resource> inplace_weak{&inplace_owner_1};
   cout << "inplace_owner_1: " << inplace_owner_1 << endl;
   cout << "inplace_weak   : " << *inplace_weak << endl;
   cout << "moving..." << endl;
   inplace_unique<Resource> inplace_owner_2 = std::move(inplace_owner_1);
   inplace_owner_1 = "inplace_resource_2";
   cout << "inplace_owner_1: " << inplace_owner_1 << endl;
   cout << "inplace_owner_2: " << inplace_owner_2 << endl;
   cout << "inplace_weak   : " << *inplace_weak << endl;
   cout << endl;
}

Вывод:
Код:
----- heap -----
heap_owner_1: heap_resource_1
heap_weak   : heap_resource_1
moving...
heap_owner_1: heap_resource_2
heap_owner_2: heap_resource_1
heap_weak   : heap_resource_1

----- inplace -----
inplace_owner_1: inplace_resource_1
inplace_weak   : inplace_resource_1
moving...
inplace_owner_1: inplace_resource_2
inplace_owner_2: inplace_resource_1
inplace_weak   : inplace_resource_2


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 11, 2020, 12:41
Тут мелькнул интересный момент, но, как всегда, растворился в дальнейшей перебранке типа "ага/угу". Утверждалось (неоднократно) что "юник" один - и только один, поэтому, дескать, никакое продление жизни для него невозможно, т.к. он немедленно станет shared, а так низзя

Вот пример из букваря
Код
C++ (Qt)
static void doDeleteLater(MyObject *obj)
{
   obj->deleteLater();
}
 
Ну а если не deleteLater а напр какой-нибудь push_back который создаст из raw указателя shared? Как видим, Qt/std против этого совсем не возражают. Да, юник один, и он отстрелялся (его delete свершилось). Но убивать сами данные никто не заставляет.
Да
Цитировать
Была докторская - стала любительская
Требуется просто "не обе вместе/одновременно". А для пресловутого продления и shared не требуется

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


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 11, 2020, 16:58
... Как бы тут гармонию навести? ...

По сути после операции move над значением, для ассоциации weak реализуется UB. То что weak без контроля доступа вообще на что-то ссылается - это скорее баг, чем фитча.


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 11, 2020, 18:15
Вот пример из букваря
Код
C++ (Qt)
static void doDeleteLater(MyObject *obj)
{
   obj->deleteLater();
}
 

Возможно, в Qt6 не будет мембера deleteLater а будет
Код:
template<class T>
static void doDeleteLater(std::unique_ptr<T> obj) { /*some metaobject magic*/ }
Но это пока гадание на кофейной гуще.

Цитировать
Ну а если не deleteLater а напр какой-нибудь push_back который создаст из raw указателя shared? Как видим, Qt/std против этого совсем не возражают. Да, юник один, и он отстрелялся (его delete свершилось). Но убивать сами данные никто не заставляет.
Вот ИМЕННО ПОЭТОМУ нельзя использовать голые указатели. "А что если я выстрелю себе в ногу, ваши вумные указатели тут не помогут". Тут либо трусы, либо крестик - либо вы забыли про слова new/delete, либо делаете все на голых указателях (и страдаете).
А shared_ptr имеет конструктор от unique_ptr и просто "расшаривает" оный.


Название: Re: C++ Object Token Library
Отправлено: _Bers от Февраль 11, 2020, 19:04
Тогда в конструкторе SomeCar (даже когда он в cpp файле находится) должен быть доступен конкретный тип SomeEngine.

да.
именно так оно и должно быть.

а вот ситуация, когда ты хочешь подсунуть фиг-знает-что,
вот это уже нежелательное осложнение.

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

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

Такая зависимость может быть нежелательна или невозможна.

приведи реальный пример для начала.

я за свою карьеру понял одну вещь:
либо у человека есть веская причина, почему он использовал фабрику (и тп выпендрёж)
либо он просто болен ООП головного мозга.








Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 09:48
По сути после операции move над значением, для ассоциации weak реализуется UB. То что weak без контроля доступа вообще на что-то ссылается - это скорее баг, чем фитча.

Вообще, такой же фокус можно и с heap_unique провернуть: std::move(*heap_owner_1) и тоже фигня получится. Ладно, это тема отдельного разговора.

А вообще нужна обёртка-токен над объектом-по-месту? Есть варианты использования, когда без неё тяжко?


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 09:51
я за свою карьеру понял одну вещь:
либо у человека есть веская причина, почему он использовал фабрику (и тп выпендрёж)
либо он просто болен ООП головного мозга.

Все программисты в мире должны писать программы так, как вы считаете правильным? Вопрос риторический, ответ известен.

"Talk is cheap, show me the code." (c). Постановка задачи выше.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 12, 2020, 10:42
Выше уже писал, что в случае с inplace (по месту владельца) смущают ситуации со сменой/перемещением ресурса. В случае с кучей, User связан с "отдельным ресурсом", в случае inplace, User связан с "ресурсом, который связан с Owner", как-то это не consistent :). Как бы тут гармонию навести?
Давайте я позадаю наивные (или даже лоховские) вопросы, это неплохой тест насколько интуитивна либа
Код
C++ (Qt)
   heap_unique<Resource> heap_owner_1 = make_unique<Resource>("heap_resource_1");
   weak<Resource>        heap_weak{heap_owner_1.get()};
   ...
   heap_unique<Resource> heap_owner_2 = std::move(heap_owner_1);
   heap_owner_1 = make_unique<Resource>("heap_resource_2");
 
Выходит безымянный юник созданный make_unique убился, но heap_unique перехватил данные (строку). А если так
Код:
auto temp = make_unique<Resource>("heap_resource_1");
heap_unique<Resource> heap_owner_1 = temp;
Так должно быть нельзя (юник один). Наверно используется какой-то хитрый конструктор &&. Ну ладно. Следующая строка (weak) вопросов не вызывает. Но вот потом.. какой рез-т ожидается от move? Что перемещаем, данные или только "оболочку"? Вроде данные, и ...weak автоматом ссылается на новый адрес(?). Не знаю насколько верны мои предположения, но во всяком случае

- плохо уже то что это не интуитивно и вызывает (ненужные) вопросы

- клиент (пользующий weak) может рассчитывать на неизменность адреса и рухнуть при его смене

- да, и интересно узнать какие резоны (или необходимость) в разделении на heap_unique и
inplace_unique? Пока не уловил в чем их половая разница

Включать "стандартную лексику" (типа "читай доку" и.т.п.) не стоит, она справедлива уже после того как решение использовать либу принято. А до того "симпатично или как"  :)


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 12, 2020, 10:51
Вот ИМЕННО ПОЭТОМУ нельзя использовать голые указатели.
Не понял этого акцента

..либо делаете все на голых указателях (и страдаете).
Да, но от вумных (вернее от их беспросветной тупости) я страдаю гораздо больше :)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 11:13
Выходит безымянный юник созданный make_unique убился, но heap_unique перехватил данные (строку). А если так
Код:
auto temp = make_unique<Resource>("heap_resource_1");
heap_unique<Resource> heap_owner_1 = temp;
Так должно быть нельзя (юник один). Наверно используется какой-то хитрый конструктор &&. Ну ладно. Следующая строка (weak) вопросов не вызывает. Но вот потом.. какой рез-т ожидается от move? Что перемещаем, данные или только "оболочку"? Вроде данные, и ...weak автоматом ссылается на новый адрес(?). Не знаю насколько верны мои предположения, но во всяком случае

- плохо уже то что это не интуитивно и вызывает (ненужные) вопросы

- клиент (пользующий weak) может рассчитывать на неизменность адреса и рухнуть при его смене

- да, и интересно узнать какие резоны (или необходимость) в разделении на heap_unique и
inplace_unique? Пока не уловил в чем их половая разница

Включать "стандартную лексику" (типа "читай доку" и.т.п.) не стоит, она справедлива уже после того как решение использовать либу принято. А до того "симпатично или как"  :)

От move ожидается такой же результат, как от move умных указателей из std, кто с ними знаком, использование токенов не должно вызывать затруднений. Перемещается, грубо говоря, связь с объектом, владение объектом.

Про разницу inplace_unique и heap_unique  ssoft расписывал (http://www.prog.org.ru/index.php?topic=32613.msg241177#msg241177). Вариант 1 - inplace, все остальные - heap.


Название: Re: C++ Object Token Library
Отправлено: Old от Февраль 12, 2020, 11:22
Да, но от вумных (вернее от их беспросветной тупости) я страдаю гораздо больше :)
А вы уверены, что причина в беспросветной тупости именно умных указателей? :)
 


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 12, 2020, 11:58
От move ожидается такой же результат, как от move умных указателей из std, кто с ними знаком, использование токенов не должно вызывать затруднений. Перемещается, грубо говоря, связь с объектом, владение объектом.
Ну значит у Вас все верно (по крайней мере формально)
Про разницу inplace_unique и heap_unique  ssoft расписывал. Вариант 1 - inplace, все остальные - heap.
Понял, типа "хранит сам". По-моему избыточно, но Вам виднее

C++ Object Token Library предоставляет примитивы, которые контроль корректности использования ассоциативных связей, перекладывают на компилятор. Некий синтаксический сахар, чтобы случайно не выстрелить себе в ногу).

Для тех, кто не готов отдать контроль корректности использования ассоциативных связей компилятору, эта библиотека не нужна.
Я бы не стал трогать такие обшие вещи как "ассоциативные связи", и не стал бы пытаться как-то замазать (вумные) "указатели", наоборот, это лучше подчеркнуть. Почему - вот пример

Пусть абстрактная задача Car/Engine/Monitor стала реальной (это легко представить, пример вполне удачен), и обзавелась небольшим UI - списком Engine. И пользователь говорит напр:
Цитировать
Спасибо, мне нравится. Но вот в списке engine мне нужно чтобы engin'ы за которыми установлены монитор(ы) показывались с оранжевыми иконками, остальные - с желтыми
Или чуть по-другому
Цитировать
При правом нажатии на айтем engine выпадает контекстное меню из которого я могу открыть один из наблюдающих мониторов, и также удалить/назначить монитор
Конечно это "смешные" задачки, и цена им 2 копейки, но... никакие вумные указатели здесь не помогут. Да, имея Monitor можно знать что он ссылается на Engine, но не наоборот, и придется заводить контейнер "ссылающихся", руками устанавливать/разрывать связи и.т.д. Тогда что толку от вумного указателя (что сидит в Monitor) если тот же ф-ционал дублирован вручную?

Думается что сама концепция (не побоюсь этого слова) вумных указателей ограничена, это как бы "билет в один конец", думки были об удобном операторе ->. И поскольку либа (или ее автор) это оставляет "как есть" - лучше про "ассоциации" не распространяться.
  


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 12:46
Я бы не стал трогать такие обшие вещи как "ассоциативные связи", и не стал бы пытаться как-то замазать (вумные) "указатели", наоборот, это лучше подчеркнуть.
...

Код можно воспринимать по разному: для одних это структуры данных и указатели между ними, для других это ресурсы и потребители, для третьих - объекты и ассоциативные связи между ними, для других ещё что-то. Причём код может быть один и тот же :). Вы, судя по всему, из первых, а я, в большинстве случаев, из третьих. Поэтому со своей колокольни и рассуждаю. Пассажи про UML в документации библиотеки можно и пропустить, если взгляд с этой стороны кого-то не интересует. Можно токены воспринимать как умные указатели с определёнными характеристиками.

Кстати, хотел сказать спасибо за то, что потратили время и предоставили свой вариант решения задачи Car. Серьёзно. Напомнили мне про старые времена, а то я уже стал забывать, как оно было, с голыми указателями :).


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 12, 2020, 14:07
А вообще нужна обёртка-токен над объектом-по-месту? Есть варианты использования, когда без неё тяжко?

Она нужна только для обеспечения однообразия интерфейса доступа к значению, чтобы вариант heap_* легко можно было заменить на inplace_* при необходимости.

По сути после операции move над значением, для ассоциации weak реализуется UB. То что weak без контроля доступа вообще на что-то ссылается - это скорее баг, чем фитча.
Вообще, такой же фокус можно и с heap_unique провернуть: std::move(*heap_owner_1) и тоже фигня получится. Ладно, это тема отдельного разговора.

Поразмышляем ... )
Ассоциативная связь агрегации с экземпляром значения является первичной. Она может быть свойством (является членом другого значения), параметром или переменной (формируется в экземпляре активности). Все остальные ассоциативные связи формируются на основании этой.

Перемещение значения из одного экземпляра уничтожает ассоциативную связь агрегации (за счет перевода экземпляра значения в неопределенное состояние, что в принципе сродни его уничтожению). Так как ассоциативная связь агрегации с таким экземпляром значения разрушается, то и все другие ассоциативные связи с ним также становятся невалидными. Использование любой связи с таким экземпляром значения является UB. Повторная инициализация экземпляра значения требует формирования всех ассоциативных связей заново.

То, что в одном случае получается такое поведение, а в другом другое - это и есть UB. С таким же успехом можно с большой вероятностью получить сохранение валидности ссылок на пересозданный экземпляр в куче (распределение нового значения легко может оказаться в том же месте, где до этого освободилась память из под старого).


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 15:38
А вообще нужна обёртка-токен над объектом-по-месту? Есть варианты использования, когда без неё тяжко?

Она нужна только для обеспечения однообразия интерфейса доступа к значению, чтобы вариант heap_* легко можно было заменить на inplace_* при необходимости.

Я тоже думал, что такая штука нужна для унификации передачи и доступа к объекту. Она должна быть перемещаемой, но связи с ней можно формировать только после того, как она "доехала до места" и после этого не двигать. Т.е. нужно следить не только за тем, чтоб объект не удалился, но и не переместился, чтобы raw::weak не стали висячими. Достаточно жёсткие требования, они меня и останавливали от inplace токена :). Но если потребность в таком есть, подумаю, чтобы добавить.

Перемещение значения из одного экземпляра уничтожает ассоциативную связь агрегации (за счет перевода экземпляра значения в неопределенное состояние, что в принципе сродни его уничтожению). Так как ассоциативная связь агрегации с таким экземпляром значения разрушается, то и все другие ассоциативные связи с ним также становятся невалидными. Использование любой связи с таким экземпляром значения является UB. Повторная инициализация экземпляра значения требует формирования всех ассоциативных связей заново.

Логично. В связи с этим, я ещё больше не понимаю упорство разработчиков gsl::not_null не допускать состояния moved-from, если можно переместить сам объект и всё равно сломать этот not_null. Они недавно даже запретили конструктор перемещения (https://github.com/microsoft/GSL/pull/842), теперь он копируется на каждый чих, даже когда std::move(not_null) пишешь :). Там ещё Herb Sutter вещает про "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)", хотя конкретно std::unique_ptr<T> нормально зануляется и тогда в его деструкторе ничего страшного не случается. Или они знают что-то такое, о чём я не подозреваю? :)


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 12, 2020, 17:03
Логично. В связи с этим, я ещё больше не понимаю упорство разработчиков gsl::not_null не допускать состояния moved-from, если можно переместить сам объект и всё равно сломать этот not_null. Они недавно даже запретили конструктор перемещения (https://github.com/microsoft/GSL/pull/842), теперь он копируется на каждый чих, даже когда std::move(not_null) пишешь :). Там ещё Herb Sutter вещает про "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)", хотя конкретно std::unique_ptr<T> нормально зануляется и тогда в его деструкторе ничего страшного не случается. Или они знают что-то такое, о чём я не подозреваю? :)

Не у всех объектов возможен валидный "null" state. У юника и вектора - возможен, с ними проблем нет.
C gsl::not_null проблема следующая:
Код:
gsl::not_null<std::unique_ptr<int>> i(new int(10));

auto j = std::move(i);
assert(i.get()); // ooops контракт нарушен, ведь i значится как NOT null, а там ноль. Как так??


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 12, 2020, 17:47
C gsl::not_null проблема следующая:
Код:
gsl::not_null<std::unique_ptr<int>> i(new int(10));

auto j = std::move(i);
assert(i.get()); // ooops контракт нарушен, ведь i значится как NOT null, а там ноль. Как так??

С чего бы вдруг? После move нет требования гарантровать работоспособность экземпляра значения. Вызов любых методов или обращение к членам является UB. i должен быть способен корректно удалиться и всё.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 17:54
Не у всех объектов возможен валидный "null" state.

Правильно. Вопрос, можно ли такие объекты вообще перемещать, и что можно с такими moved-from объектами делать? То, что к ним лучше не обращаться - это понятно. Их надо либо не трогать, чтоб они удалились или присвоить им новое значение, если это возможно. Т.е. в общем-то, к moved-from объекту можно относиться как-будто его удалили, и последующие возможные обращения к нему считать невалидными и отслеживать статическими анализаторами. Простые случаи уже отлавливаются, например, Clang-Tidy bugprone-use-after-move (https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html), в CppCheck тоже подобная диагностика есть.

C gsl::not_null проблема следующая:
Код:
gsl::not_null<std::unique_ptr<int>> i(new int(10));

auto j = std::move(i);
assert(i.get()); // ooops контракт нарушен, ведь i значится как NOT null, а там ноль. Как так??

В строке assert(i.get()); статический анализатор (а лучше сам компилятор), должен выдавать предупреждение о доступе к moved-from объекту.

Вот на такой код:
Код
C++ (Qt)
#include <otn/all.hpp>
#include <iostream>
 
int main()
{
   otn::unique<int> i(new int(10));
 
   auto j = std::move(i);
   std::cout << *i << std::endl;
}
у меня прямо сейчас выводятся предупреждение для строки std::cout << *i << std::endl; от CppCheck и Clang-Tidy.

Т.е. в этом отношении, всё что требуется от not_null после перемещения - это спокойно умереть и не выкинуть какой-нибудь фокус в деструкторе.

По-моему, от запрета перемещения они больше проблем поимеют, чем "защитят" его.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 12, 2020, 18:14
После move нет требования гарантровать работоспособность экземпляра значения. Вызов любых методов или обращение к членам является UB. i должен быть способен корректно удалиться и всё.

Да, но некоторые типы объектов после перемещения находятся в валидном определённом состоянии. Например, те же умные указатели std, которые, по классификации CppOtl являются optional.

Код
C++ (Qt)
#include <memory>
#include <iostream>
 
int main()
{
   auto i = std::make_shared<int>(10);
   auto j = std::move(i);
   auto k = i;
   std::cout << *j << std::endl;
}

Анализаторы возбуждаются на auto k = i;, хотя код валидный. Нужно как-то эти случаи различать и научить анализаторы их корректно обрабатывать.


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 12, 2020, 19:32
Да, но некоторые типы объектов после перемещения находятся в валидном определённом состоянии. Например, те же умные указатели std, которые, по классификации CppOtl являются optional.
Анализаторы возбуждаются на auto k = i;, хотя код валидный. Нужно как-то эти случаи различать и научить анализаторы их корректно обрабатывать.

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

Если реально необходимо произвести обмен значениями, то нужно использовать swap.


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 13, 2020, 08:39
Перемещение значения из одного экземпляра уничтожает ассоциативную связь агрегации (за счет перевода экземпляра значения в неопределенное состояние, что в принципе сродни его уничтожению). Так как ассоциативная связь агрегации с таким экземпляром значения разрушается, то и все другие ассоциативные связи с ним также становятся невалидными. Использование любой связи с таким экземпляром значения является UB. Повторная инициализация экземпляра значения требует формирования всех ассоциативных связей заново.
На том же примере
Код
C++ (Qt)
   heap_unique<Resource> heap_owner_1 = make_unique<Resource>("heap_resource_1");
   weak<Resource>        heap_weak{heap_owner_1.get()};
   ...
   heap_unique<Resource> heap_owner_2 = std::move(heap_owner_1);
Верно ли я понял что heap_weak.get() должен возвращать null после move ?


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 13, 2020, 08:44
Напомнили мне про старые времена, а то я уже стал забывать, как оно было, с голыми указателями :).
К сожалению, далеко не весь ф-ционал реализованный "в лоб" достижим с Вашей либой. Конечно это нормально (есть область применения и.т.п.), но все-таки хотелось бы.
Код:
Рано еще утюжок бросать
:)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 09:44
То что что-то остается в валидном состоянии - это всего лишь удобство реализации, просто полное уничтожение экземпляра может быть нерациональным с точки зрения производительности, для таких экземпляров вводят термин "частично сформированный". В общем случае move - это способ показать явно, что более данный экземпляр значения использован не будет (указание намерения уничтожения до окончания области видимости). Валидность экземпляра значения после move не гарантируется. Это, конечно, не является обязательным требованием, однако в общем случае лучше делать так, чтобы не иметь логических разночтений.

Валидность экземпляра значения после move зависит от операции, обычно это move constructor и move assignment operator, и в них определяется (указывается в документации, если она есть :)), в каком состоянии останется объект-источник. Обычно там выполняется swap с объектом, созданным конструктором по умолчанию, если он есть. Так что swap "снаружи", или какие-то другие действия по инициализации в "пустое" состояние, могут быть избыточными и неудобными в использовании. По-моему, эта ситуация похожа на noexcept, можно, например атрибутами для Lifetime Profile, как-то помечать, в каком состоянии окажется объект после перемещения, чтобы предоставить  статическим анализаторам больше информации.

Если реально необходимо произвести обмен значениями, то нужно использовать swap.

Вот со swap у gsl::not_null проблемы и начнутся :) Когда они сделают = delete для move construction и move assignment, то отвалится std::swap, и придётся лепить костылик. Мелочь, но всё же. Потом возникнет вопрос, что можно с таким неперемещаемым gsl::not_null<unique> вообще делать? Не удивлюсь, что чуть меньше, чем ничего :).


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 09:52
К сожалению, далеко не весь ф-ционал реализованный "в лоб" достижим с Вашей либой. Конечно это нормально (есть область применения и.т.п.), но все-таки хотелось бы.

Правильно, есть область применения. Библиотека не претендует на исполнение всех желаний всех желающих :).


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 13, 2020, 11:30
Валидность экземпляра значения после move зависит от операции, обычно это move constructor и move assignment operator, и в них определяется (указывается в документации, если она есть :)), в каком состоянии останется объект-источник. ...

Технически конечно всё зависит от реализации. Можно запрограммировать вообще любое действие. Можно и операторы переопределить и получить совершенно другую математику. Но на действие бинарного оператора "+" предполагается реализация понятия суммы, на действие бинарного оператора "-" - реализация разности, на метод "swap" - обмен значениями, оператор присвоения "=" с rvalue справа предполагает перенос значения справа налево и оставление правой части в частично сформированном виде не пригодном для полноправного использования.

Стандарт вводит такие положения:

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
Objects of types defined in the C++ standard library may be moved from ( 15.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.

20.3.25 [defns.valid]
valid but unspecified state
value of an object that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type
[Example: If an object x of type std::vector<int> is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. — end example ]

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

Может дать предложение по изменению стандарта  ;D ;D ;D ?

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
... Unless otherwise specified, such moved-from objects shall be placed in a unspecified but destructible state.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 11:46
Не все типы могут иметь какое-то дефолтное валидное состояние, в которое можно перейти после операции перемещения. Вполне можно использовать опцию (Unless otherwise specified) и явно указать невозможность использования для таких типов, что на самом деле в общем виде логически и подразумевается.

Согласен. По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству. Я к тому, что не всё так однозначно, как "надо всё запретить и не пущать" :). Касательно not_null поведение анализатора по умолчанию и будет срабатывать.

Кстати, нужны ещё диагностики, чтобы доступ к optional-like объекту осуществлялся только после проверки, что в нём что-то есть.

Может дать предложение по изменению стандарта  ;D ;D ;D ?

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
... Unless otherwise specified, such moved-from objects shall be placed in a unspecified but destructible state.

Судя по тому, что Herb Sutter говорит про "C++ gets something along the lines of the relocation / destructive move semantics proposals, where roughly "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)", значит что-то ещё думают в этом направлении, может и формулировки поменяют. Но не скоро :).


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 12:36
Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.

И тем не менее это так https://lists.qt-project.org/pipermail/development/2020-January/038544.html

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 13, 2020, 15:31
А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?
Вооот
Цитировать
..хорошо хоть задумываться начали
(как один тут говорил :)). Полагаю что точно так же как сейчас, std здесь ничего не дает

По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству.
Откуда возникают такие сложности, не надуманы ли они?


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 13, 2020, 15:37
А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?

Например, так (https://codereview.qt-project.org/c/qt/qtbase/+/231543)


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 17:27
А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?

Например, так (https://codereview.qt-project.org/c/qt/qtbase/+/231543)

Понятно, что это наброски, подмазали косметикой, и придираться к этому не стоит...

Но вот например T* adoptChild(std::unique_ptr<T> child) (https://codereview.qt-project.org/c/qt/qtbase/+/231543/2/src/corelib/kernel/qobject.h#424):
Код
C++ (Qt)
template<class T>
T* adoptChild(std::unique_ptr<T> child) {
   child->setParent(this);
   return child.release();
}

Здесь подходящий случай, чтобы использовать gsl::not_null<std::unique_ptr<T>>? Или допустимо, что child может быть nullptr?

Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?
Код
C++ (Qt)
template<class T>
void adoptChild(T *child);
 
template<class T>
T* adoptChild(std::unique_ptr<T> child);


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 13, 2020, 17:48
На том же примере
Код
C++ (Qt)
   heap_unique<Resource> heap_owner_1 = make_unique<Resource>("heap_resource_1");
   weak<Resource>        heap_weak{heap_owner_1.get()};
   ...
   heap_unique<Resource> heap_owner_2 = std::move(heap_owner_1);
Верно ли я понял что heap_weak.get() должен возвращать null после move ?

Неверно. heap_weak связан с heap_resource_1, и он никуда не делся, просто сменился его владелец. Так что heap_weak остался связан с heap_resource_1.

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?
Вооот
Цитировать
..хорошо хоть задумываться начали
(как один тут говорил :)). Полагаю что точно так же как сейчас, std здесь ничего не дает

Для такой огромной кодовой базы родом из 90-х, умные указатели действительно мало что дадут. Полагаю, Qt до скончания своих веков будет на голых указателях жить. Если менять на умные нормально, там много чего переделывать придётся, и это будет уже совсем другой Qt. Но это не значит, что надо опустить руки и ничего не делать :).

По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству.
Откуда возникают такие сложности, не надуманы ли они?

Может и надуманы, но это надо проверить :). А для этого надо подумать ещё лучше.


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 13, 2020, 18:38
Понятно, что это наброски, подмазали косметикой, и придираться к этому не стоит...

Но вот например T* adoptChild(std::unique_ptr<T> child) (https://codereview.qt-project.org/c/qt/qtbase/+/231543/2/src/corelib/kernel/qobject.h#424):
Код
C++ (Qt)
template<class T>
T* adoptChild(std::unique_ptr<T> child) {
   child->setParent(this);
   return child.release();
}

Здесь подходящий случай, чтобы использовать gsl::not_null<std::unique_ptr<T>>? Или допустимо, что child может быть nullptr?

Да, вполне. Ну или метод должен на nullptr проверять.

Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?
Код
C++ (Qt)
template<class T>
void adoptChild(T *child);
 
template<class T>
T* adoptChild(std::unique_ptr<T> child);

Первый метод должен возвращать T * естессно чтобы код выглядел унифицированно.
У данного решения есть огромный плюс - оно на уровне сорцов совместимо со старым кодом. Что позволяет объявить конструкторы от QObject * и setParent() deprecated и сказать всем - юзайте parent->adoptChild(child) вместо child->setParent(parent). Первый метод позволяет сделать замену тривиальной.
Второй, после того, как произошла замена, позволяет потихоньку добавить современного с++.


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 14, 2020, 11:19
Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?

Если честно - полное отсутствие каких-либо мыслей)). Это какое-то изнасилование unique_ptr ( использовали child->setParent(this); и выбросили child.release(); ).
Нужно сначала понять преследуемую цель применения здесь умных указателей. Если для внутреннего использования, чтобы с исключениями можно нормально работать было - это одно; если добавить заплатки для тех, кто использует умные указатели - другое; если еще что-то - то третье.


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 14, 2020, 12:19
Очевидно, что цель патча не переписать внутренности QObject а продемонстрировать API и то, что оно совместимо с текущим кодом. Это как бы важнее того как "у ей внутре" оно реализовано. Да, там будет просто мув юника во внутренний вектор (и это тоже очевидно), но это деталь реализации совершенно не важная на данный момент


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 14, 2020, 14:29
У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось (то есть в той же Qt QPointer юзается ровно по той причине что все виджеты в главном потоке и "продлять жизнь" не надо). Но ВНЕЗАПНО не все с++ погромисты пишут ГУИ тулкит и не у всех есть требование "только в главном потоке".

А если бы QPointer был потокобезопасным, у него было бы больше юзкейсов? Насколько активно этим бы пользовались?


Название: Re: C++ Object Token Library
Отправлено: Igors от Февраль 14, 2020, 15:01
А если бы QPointer был потокобезопасным,
Кстати - а можно код Вашей реализации move? (ну или обеспечивающего конструктора). Хочу посмотреть как там с (без)опасностью. Спасибо


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 14, 2020, 15:21
Кстати - а можно код Вашей реализации move? (ну или обеспечивающего конструктора). Хочу посмотреть как там с (без)опасностью. Спасибо

Вы какие-то неприличные вопросы задаёте для open source библиотеки под MIT лицензией расположенной на популярном хостинге репозиториев :). CppOtl examples (https://gitlab.com/CppObjectTokens/Complex/Example), пример Car как раз про многопоточность. Можете скачать,  рассматривать и пытать как душе угодно. Если коротко, то move в токенах такой же, как в умных указателях std.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 19, 2020, 12:03
Свежак от Herb Sutter: Move, simply (https://herbsutter.com/2020/02/17/move-simply/).

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

У Герба другое мнение :):
Цитировать
...
Can a given type document that moving from an object always changes its state? or changes it to a known state?

Yes, move is just another non-const function. Any non-const function can document when and how it changes the object’s state, including to specify a known new state as a postcondition if it wants. For example, unique_ptr‘s .release() function is guaranteed to set the object to null — just as its move functions are guaranteed to set the source object to null.

...

Does “but unspecified” mean the object’s invariants might not hold?

No. In C++, an object is valid (meets its invariants) for its entire lifetime, which is from the end of its construction to the start of its destruction. Moving from an object does not end its lifetime, only destruction does, so moving from an object does not make it invalid or not obey its invariants.

If any non-const function on an object (including moving from it) makes the object invalid, the function has a bug.
...

Там же обсуждение в комментах. Понравился такой (https://herbsutter.com/2020/02/17/move-simply/#comment-41134) :):
Цитировать
steve heller

If that’s the simple explanation, I don’t want to see the complex one.

Ещё на reddit:
Move, simply – Sutter’s Mill (https://www.reddit.com/r/cpp/comments/f5co9g/move_simply_sutters_mill/).
Сразу же появился "Наш ответ Чемберлену": move, even more simply (https://www.reddit.com/r/cpp/comments/f5ufsa/move_even_more_simply/).

Ещё про перемещение:
Object relocation in terms of move plus destroy (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1144r4.html).
move = bitcopies (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1029r3.pdf).


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 20, 2020, 09:09
Свежак от Herb Sutter: Move, simply (https://herbsutter.com/2020/02/17/move-simply/).
У Герба другое мнение :):

Конечно, хотелось бы видеть теоретическое обоснование, а не толкование стандарта. А так ... можно и поспорить))).
Хотя, где я, и где Herb  ;D

Не будем не рассматривать возможные специализации функции move, возьмем только стандартную реализацию.
И пройдемся по некоторым положениям свежака).

Цитировать
If any non-const function on an object (including moving from it) makes the object invalid, the function has a bug.

Действительно, простое применение функции move никогда не делают никакой объект инвалидом). Можно хоть миллион раз вызвать move.
Работают здесь по настоящему либо конструктор, либо оператор перемещения (такие специальные для работы с rvalue значениями).

Цитировать
... C++ already uses move automatically when copying from an object it knows will never be used again, such as a temporary object or a local variable being returned or thrown from a function.

Как видно, критерием автоматического применения move является знание, что экземпляр объекта не используется снова. Как правило, это временные объекты, которые разрушаются сразу после перемещения. Использование move является принудительным преобразованием к виду rvalue, подобного временному объекту, который после операции перемещения применять в дальнейшем не предполагается.

Если разделить экземпляр объекта на две составляющие - значение и токен (то, посредством чего можно обратиться к значению), то можно заметить, что rvalue - это значение без токена, а lvalue с токеном. Логически операция move подразумевает перемещение значения из одного места в другое, и если токен (а не значение) после извлечения из него значения станет инвалидом в чем здесь проблема? Если от донора к акцептору пересадить сердце, останется ли жив донор?

Herb рассматривает пример с IndirectInt
Цитировать
Код
C++ (Qt)
// Buggy class: Move leaves behind a null smart pointer
class IndirectInt {
   shared_ptr<int> sp = make_shared<int>(42);
public:
   // ... more functions, but using defaulted move functions
   bool operator<(const IndirectInt& rhs) const { return *sp < *rhs.sp; }
                                               // oops: unconditional deref
   // ...
};
IndirectInt i[2];
i[0] = move(i[1]); // move leaves i[1].sp == nullptr
sort(begin(i), end(i)); // undefined behavior
 

Здесь поменяны местами причина и следствие. Утверждение, что класс некорректен следует из утверждения, что некорректным является рассмотренное поведение. Интересно, а что будет, если рассмотреть такой вариант?

Код:
double i[2];
i[1] = std::nan("0");
sort(begin(i), end(i)); // undefined behavior

Еще одно утверждение

Цитировать
... users won’t always know if a given object they encounter is moved-from. For example:
Код
C++ (Qt)
void f(const IndirectInt& a, const IndirectInt& b) {
   if (a < b)  // this would be a bug without first testing (somehow) that a and b both aren't moved-from
      // ...
}
 

не является правдой! Пользователь функции, вызывающий f( a, b ), всегда знает перемещались ли a или b до момента вызова. Разработчик же функции не обязан контролировать существование значений у неопциональных параметров.

Ну и корень всего)

Цитировать
Does the “moved-from” state correspond to the “partially formed but not well formed” described in Elements of Programming(aka EoP)?
Not quite.

In EoP, the description of an object’s state as “partially formed but not well formed” is similar to the C++ Standard’s description of “valid but unspecified.” The difference is that EoP requires such objects to be assignable and destroyable (i.e., partially formed) while the C++ standard makes a broader statement that “operations on the object behave as specified for its type” and that a moved-from object “must still meet the requirements of the library component that is using it.” (See Cpp17MoveConstructible and Cpp17MoveAssignable.)

Собственно, из такой формулировки стандарта делаются все выводы о некорректности той или иной реализации выше. При этом такая логическая модель перемещения (первичная по отношению к языку программирования) является противоречивой, в отличие от модели EoP. При этом пример not_null именно и показывает на практике противоречивость модели. Следовательно требуется корректировка стандарта. При этом многие пользователи языка и разработчики статических анализаторов сделали вывод о том, что лучшей практикой является считать, что перемещенный экземпляр объекта лучше не трогать).

А так это похоже на известный анекдот - "Ежики плакали и кололись, но продолжали жрать кактус".


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 20, 2020, 11:20
Пользователь функции, вызывающий f( a, b ), всегда знает перемещались ли a или b до момента вызова.

Вряд ли всё так просто. Ситуации с перемещением наверняка стоит рассматривать наравне с "common dangling", которые анализируются в "Lifetime safety: Preventing common dangling (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1179r1.pdf)". Интересно, что в "Reply-to" этого документа числится... Herb Sutter :). Может ему надоело возиться с dangling pointers и не охота ещё и с перемещением заморачиваться, вот он и топит за то, чтоб после перемещения объекты были в валидном состоянии и не надо было диагностик для этого делать )).

По “valid but unspecified” наверное только ленивый не прошёлся :). Мне ещё интересно, как одновременно уживаются две мысли: "Moving from an object does not end its lifetime, only destruction does, so moving from an object does not make it invalid or not obey its invariants." и "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)" :).

Вообще, хотелось бы получить какую-нибудь золотую середину: в общем случае к moved-from объекту обращаться нельзя, но в postcondition (когда Contracts доделают) можно указать, в каком состоянии окажется перемещённый объект, чтобы компилятор и анализаторы могли использовать эту информацию. Всё таки есть объекты, которые после перемещения могут переходить в определённое валидное состояние.


Название: Re: C++ Object Token Library
Отправлено: ssoft от Февраль 20, 2020, 13:54
Всё таки есть объекты, которые после перемещения могут переходить в определённое валидное состояние.

Исходя из требования модели или особенности технической реализации?


Название: Re: C++ Object Token Library
Отправлено: Авварон от Февраль 20, 2020, 18:29

Мне ещё интересно, как одновременно уживаются две мысли: "Moving from an object does not end its lifetime, only destruction does, so moving from an object does not make it invalid or not obey its invariants." и "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)" :).


Move и "destructive move" таки разные вещи. Второй в природе не существует и народ обсуждает, а нужна ли она или стремно.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 21, 2020, 10:51
Всё таки есть объекты, которые после перемещения могут переходить в определённое валидное состояние.

Исходя из требования модели или особенности технической реализации?

Одно другому не мешает :). Те же самые умные указатели std при перемещении "зануляются" в реализации, что соответствует переходу в "пустое" состояние для optional-like объекта. И выглядит это вполне логично:

Код
C++ (Qt)
#include <memory>
#include <iostream>
 
class Label
{
public:
   using Caption = std::unique_ptr<std::string>;
 
   Label() = default;
   explicit Label(Caption caption) noexcept
       : m_caption{std::move(caption)}
   {}
 
   Caption releaseCaption() noexcept
   { return std::move(m_caption); }
 
   void print() const
   {
       std::cout << "Caption: " << (m_caption ? *m_caption : "[none]")
                 << std::endl;
   }
 
private:
   Caption m_caption;
};
 
int main()
{
   Label label{std::make_unique<std::string>("Hello!")};
   label.print();
   label.releaseCaption();
   label.print();
}

Как будет выглядеть Label::releaseCaption(), если придётся вручную переинициализировать m_caption?


Название: Re: C++ Object Token Library
Отправлено: ViTech от Февраль 21, 2020, 11:15
Move и "destructive move" таки разные вещи. Второй в природе не существует и народ обсуждает, а нужна ли она или стремно.

Что "destructive move" ещё в природе не существует, то я в курсе. Правда ещё не изучал внимательно, что там предлагают. Я всё пытаюсь расшифровать это высказывание (https://github.com/microsoft/GSL/pull/842#issuecomment-582074941) Саттера:
Цитировать
Yes, an intended effect of this change is that a not_null<unique_ptr<T>> can only sit there, it can't be moved anywhere. But this is already inherently true, moving one of those is impossible today without breaking the not_null invariant. The correct long-term answer for this would be if C++ gets something along the lines of the relocation / destructive move semantics proposals, where roughly "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called), then that would naturally enable cases like returning a local not_null<unique_ptr<T>> by value.

С одной стороны запрещают перемещение not_null, чтобы он не оказался в невалидном состоянии, с другой он говорит, что "relocation/destructive move" чем-то поможет. Я явно что-то упускаю в логике Саттера :). Возможности только "returning a local not_null<unique_ptr<T>> by value", по-моему, маловато будет для полноценного использования not_null<unique>.


Название: Re: C++ Object Token Library
Отправлено: ViTech от Июнь 29, 2020, 12:14
"C++ Move Semantics - The Complete Guide" now Feature Complete (https://isocpp.org/blog/2020/06/cpp-move-semantics-the-complete-guide-now-feature-complete). Всё, что нужно знать про перемещение. Всего-то страниц 200 :).


Название: Re: C++ Object Token Library
Отправлено: ViTech от Июнь 30, 2020, 11:02
А вообще нужна обёртка-токен над объектом-по-месту? Есть варианты использования, когда без неё тяжко?

Она нужна только для обеспечения однообразия интерфейса доступа к значению, чтобы вариант heap_* легко можно было заменить на inplace_* при необходимости.

Кстати, добавил в библиотеку raw::unique[_single] и raw::unique_optional для "inplace-объектов".


Название: Re: C++ Object Token Library
Отправлено: ViTech от Август 19, 2020, 10:59
Про отношения между объектами в картинках: unique_ptr, shared_ptr, weak_ptr, or reference_wrapper for class relationships (https://www.nextptr.com/tutorial/ta1450413058/unique_ptr-shared_ptr-weak_ptr-or-reference_wrapper-for-class-relationships).