Viacheslav
Значит они решили, что наблюдение без владения лучше объяснить словом observe.
Constantine
Owner и observer — две абсолютно разные вещи.
да, только обертка опционального владельца объекта это в точности observer_ptr
Viacheslav
Это не опциональный владелец. Это просто сторонний наблюдатель, который никак на владение объектом не влияет.
Constantine
потому что observer_ptr семантически выражает внешнее владение обернутым указателем, которое в силу логических доказательств приводит к постоянному существованию этого объекта
Viacheslav
Не знаю, откуда у Вас такое понимание слова observe. Ничего такого оно семантически не означает.
Constantine
Не знаю, откуда у Вас такое понимание слова observe. Ничего такого оно семантически не означает.
It is intended as a near drop-in replacement for raw pointer types, with the advantage that, as a vocabulary type, it indicates its intended use without need for detailed analysis by code readers.
Viacheslav
Ну и где тут хоть что-то, что переводится как "владеть"?
Constantine
Ну и где тут хоть что-то, что переводится как "владеть"?
Задумайтесь, почему вы вообще можете разыменовать указатель, которым вы НЕ ВЛАДЕЕТЕ (владение выражается в shared/unique/weak)
Viacheslav
Задумайтесь, почему вы вообще можете разыменовать указатель, которым вы НЕ ВЛАДЕЕТЕ (владение выражается в shared/unique/weak)
Потому что мы наблюдаем за сторонним объектом, к иерархии владения которым не имеем вообще никакого отношения?
Constantine
Существует ровно два случая, когда мы можем разыменовать указатель - (а) мы знаем, что мы сдохнем раньше и (б) нас оповестят
Viacheslav
Но при этом мы точно знаем, что этот указатель можно разыменовать?
Нет. Этот тип, в отличие от сырого указателя, точно показывает, что мы никак не владеем ресурсом и не должны его трогать.
Max
Если вкратце, какой смысл weak_unique_ptr ?
Viacheslav
Нет. Этот тип, в отличие от сырого указателя, точно показывает, что мы никак не владеем ресурсом и не должны его трогать.
C++ не Rust, поэтому гарантий валидности разыменовывания, кроме документации, всё равно нет.
Constantine
C++ не Rust, поэтому гарантий валидности разыменовывания, кроме документации, всё равно нет.
> Существует ровно два случая, когда мы можем разыменовать указатель - (а) мы знаем, что мы сдохнем раньше и (б) нас оповестят
Constantine
в случае (а) это обратная ссылка на владеющий объект, которая только по очень вселенской причине может быть не reference_wrapper
Viacheslav
Ну и что не так-то, я не пойму? Когда у тебя Blah* где-то в кишках, то никакой дополнительной информации это не несёт. observer_ptr<Blah> точно семантически показывает, что мы объектом не владеем.
Anonymous
Красивое название для обычных указателей.
Constantine
Я не понимаю, почему этот класс называется не "pointer_wrapper"
Viacheslav
Constantine
Я использовал "не владеть".
wrapper не владеет объектом
Anonymous
Ну и что не так-то, я не пойму? Когда у тебя Blah* где-то в кишках, то никакой дополнительной информации это не несёт. observer_ptr<Blah> точно семантически показывает, что мы объектом не владеем.
Viacheslav
Я не понимаю, почему этот класс называется не "pointer_wrapper"
Если хочется до**аться до семантики, то observer_ptr — это не wrapper.
Viacheslav
Он ничего не оборачивает.
Anonymous
wrapper не владеет объектом
Не думаю, что это так в подавляющем числе случаев.
Constantine
Он ничего не оборачивает.
Хорошо, так мне делать класс observer_ref?
Constantine
То же самое, только никогда не null? Методом using observer_ref = reference_wrapper?
Constantine
replacement for raw pointer types
Berkus
потому что observer_ptr семантически выражает внешнее владение обернутым указателем, которое в силу логических доказательств приводит к постоянному существованию этого объекта
нет, семантически он как раз выражает weak_ptr который не владеет, и ни к чему не приводит, ЧТО И НАПИСАНО В ДОКУМЕНТАЦИИ К ЭТОМУ КЛАССУ ВО ВТОРОЙ СТРОКЕ
Constantine
и речь идет об указателе, который НИКОГДА не будет разыменован?
Berkus
с первым соглашусь, со вторым не очень
Constantine
пойду писать пропоуз на pointer_wrapper
Berkus
удачи!
Constantine
хм....
Constantine
у него таки есть operator*operator-> dereferences pointer to the watched object
Viacheslav
И что тебя смущает-то? Он ведёт себя как сырой указатель.
Berkus
ты прямо жирный тролль похоже, прямо очень жирный
Berkus
у меня пальцы к клавиатуре начинают прилипать
Constantine
ты прямо жирный тролль похоже, прямо очень жирный
Не, я просто лишний раз ударился об стену с кирпичом утром
Constantine
и речь идет об указателе, который НИКОГДА не будет разыменован?
Я все еще раз внимательно перечитал. Вот для этого нужен отдельный класс, а observer_ptr должен называться pointer_wrapper и создаваться через std::ptr
Viacheslav
А зачем вообще нужен указатель, который нельзя разыменовать? Какой в нём тогда смысл, как доступ к данным получить-то?
Constantine
В одной ОС, которую нельзя называть, такие указатели называются HANDLE
Constantine
И используются чуть меньше, чем в каждой API
Viacheslav
HANDLE — это opaque type.
Viacheslav
То, что это указатель, тебя вообще волновать не должно.
Viacheslav
Это может быть число, как в Unix, или какая-нибудь структура.
Constantine
Только HANDLE имеет размер указателя <s>и крякает как void*</s>
Viacheslav
Если его только в API передавать, то крякает он как тип, о котором ты вообще ничего не знаешь. И точка.
Viacheslav
Это даже не void* для тебя должен быть.
Constantine
Причем CopyConstructible как указатель
Constantine
Так что IncompleteType* в точности совпадает семантически
Constantine
Тем более, что нет ни одной причины ему не быть IncompleteType* и использовать лишний ремаппинг
Viacheslav
Неверно. Я знаю, что этот тип CopyConstructible
Ну давай сделаем домашнее задание, запихни этот HANDLE в какой-нибудь свой класс и напиши meaningful CopyConstructible semantics для обёртки.
Viacheslav
Когда не получится, расскажи про CopyConstructible для абстрактного ресурса.
Constantine
И спрошу у вас, понимаете ли вы, что void* это копируемое значение
Viacheslav
А я, пожалуй, скажу, что у класса, содержащего handle, без доступа к дополнительному API нет и не может быть никакого copy constructor. Потому что ты понятия не имеешь, как копирование абстрактного ресурса себя поведёт. И как его освобождать.
Viacheslav
Потому что, внезапно, есть CloseHandle.
Viacheslav
Потому что, внезапно, есть CloseHandle.
Так что разговор я считаю закрытым, Вы разницу между opaque object which owns something and has to be released to avoid resource leaks and a simple observer не видите.
Constantine
Так что разговор я считаю закрытым, Вы разницу между opaque object which owns something and has to be released to avoid resource leaks and a simple observer не видите.
Угу, я согласен. Вы упорно не понимаете, что копирование не означает копирование нижележащего ресурса и понятие "копия" определено семантически по-разному для значения и указателя (в том числе shared_ptr)
Viacheslav
Когда поймёшь, что handle — это не просто указатель, даже если это внутри typedef to void*, тогда и поговорим.
Stanislav
shared_ptr<HANDLE>
Constantine
Когда поймёшь, что handle — это не просто указатель, даже если это внутри typedef to void*, тогда и поговорим.
Ага, мне только осталось выяснить, какой код сломается, если в win header-ах использовать using HWND = std::experimental::observer_ptr<IncompleteWndType>;
Constantine
А вот если написать using HWND = std::unique_ptr<IncompleteWndType>, у вас ляжет весь код
Viacheslav
А какой валидный код сломается, если там будет using HWND = struct blah { ... };?
Viacheslav
Если тебе сказали, что это opaque type, и ты про него вообще ничего не должен знать?
Constantine
А какой валидный код сломается, если там будет using HWND = struct blah { ... };?
Запретите структуре конструктор копирования
Constantine
И скажите, как вызывать CreateWindow
Viacheslav
Зачем? Это POD тип.
Viacheslav
Не делай никаких assumptions о том, что там лежит. И передавай в API. Всё.