170 похожих чатов

Есть ли смысл использовать std::optional<std::reference_wrapper<T>> вместо T*?

35 ответов

8 просмотров

спорный вопрос. если кодовая база так устроена, что в ней очевидно, что T* - это optional<T&>, то можно ограничиться и T*.

У них разная семантика. std::shared/unique_ptr – возможно, а std::optional<std::reference_wrapper<T>> довольно неудобная для использования штука

Алиса Королёва
чем неудобная?

Например, двойным разыменованием или излишней длиной сигнатур

Алиса-Королёва Автор вопроса
Ofee Oficsu
Например, двойным разыменованием или излишней длин...

а преимущества перед сырым указателем есть?

Когда речь идет об std::optional - лучше, имхо, посмотреть не в сторону указателей, а каких-нибудь "атомарных" ресурсов, которые могут, например, не поставляться интерфейсу в рамках утвержденного контракта. Ближе всего будут всевозможные handle'ы. Однако, наверное, подобную архитектуру в идеальном случае вообще лучше не иметь. Не припоминается случай, когда handle'ы не являются указателями на агрегаты в не-opaque архитектурах (как какой-нибудь OpenGL, например).

Алиса Королёва
а преимущества перед сырым указателем есть?

Надо смотреть есть ли перегрузка у optional для reference_wrapper, не занимает ли больше места для хранения флага

Nikita Khomutov
Это вкусовщина и не более

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

Алиса Королёва
а преимущества перед сырым указателем есть?

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

Ofee Oficsu
Ну, двойная абстракция и необходимость двойного ра...

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

Alexander Karaev
специализации точно нет

Значит, вот и ответ, чем сырой указатель лучше

Nikita Khomutov
Значит, вот и ответ, чем сырой указатель лучше

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

Sergey Anisimov
Если нужна явная индикация того, что указатель мож...

Указатель и так явно nullable по определению. Для non-nullable есть reference

Nikita Khomutov
Указатель и так явно nullable по определению. Для ...

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

Sergey Anisimov
На это совершенно необязательно так смотреть. Я, н...

Не, лучше именно так и смотреть. C++ Core Guidelines не просто так были написаны. > если будет осуществляться запись Тут уже не понял, не const-ли семантику ли вешаете на поинтер?

Nikita Khomutov
Не, лучше именно так и смотреть. C++ Core Guidelin...

Не понял Вашего непонимания. out-var'ы (в т.ч. POD'ы) могут для записи быть переданы через Lvalue-ссылку или указатель. В этой ситуации я требую указатель, чтобы лишний раз стимулировать понимание записывающей природы вызываемой конструкции. Можно это, конечно, счесть за идиосинкразию, но, имхо, вполне адекватный пример потенциальной семантической разницы. Кроме того, повидал не один проект (в т.ч. весьма большие), в который указатели совершенно не означали допустимость нуллирования.

Sergey Anisimov
Не понял Вашего непонимания. out-var'ы (в т.ч. POD...

Значит я правильно понял, что вместо того, чтобы использовать встроенную в язык const-семантику, вы вместо этого используете поинтеры вместо lvalue reference? Кажется, этот подход изначально ошибочен: в языке уже есть готовый инструмент для этой задачи. А отличие lvalue от pointer только в свойстве nullable

Nikita Khomutov
Значит я правильно понял, что вместо того, чтобы и...

К чему в данной ситуации вообще упоминание const-семантики? auto subA ( Type const& data ) -> /* ... */; auto subB ( Type& data ) -> /* ... */; Для вызывающего контекста вызовы с передачей экземпляра Type будут синтаксически неотличимы. Иными словами, именно вызывающей стороне нужно следить за const-семантикой, чтобы не выстрелить в ногу. Если же мы имеем auto subB ( Type* data ) -> /* ... */; вызывающей стороне потребуется препенднуть амперсанд. Это, конечно, ничего не гарантирует, но в примитивном коде сериализации/десериализации отрезвляет весьма эффективно.

Sergey Anisimov
К чему в данной ситуации вообще упоминание const-с...

Ну как это не отличимы? Для вызова subA гарантируется, что у data вызываются только const-методы (кроме случая const_cast, но это умышленное нарушение контракта). Для subB контракт другой.

Nikita Khomutov
Ну как это не отличимы? Для вызова subA гарантируе...

Абсолютно верно. Однако, неконстантный объект можно отдать в оба. В этом и проблема.

Sergey Anisimov
Абсолютно верно. Однако, неконстантный объект можн...

Так в чём проблема? Пока никакой проблемы нет

Nikita Khomutov
Ну как это не отличимы? Для вызова subA гарантируе...

SomeDamnedFileHeader hdr; doSmthngA(hdr); doSmthngB(hdr); doSmthngC(hdr); После какого вызова hdr изменился? Изменился ли он вообще? Ждали ли Вы изменения в этом месте?

Nikita Khomutov
Так в чём проблема? Пока никакой проблемы нет

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

Sergey Anisimov
SomeDamnedFileHeader hdr; doSmthngA(hdr); doSmthng...

Мне IDE подсветит, где hdr был взят как T&, а не как const T&

Nikita Khomutov
Мне IDE подсветит, где hdr был взят как T&, а не к...

А мне компилятор проэррорит, если я сделаю не то, что предполагал. Это все-таки существенная разница.

Sergey Anisimov
А мне компилятор проэррорит, если я сделаю не то, ...

Ну так если явно хочешь это зарестриктить, то проще const auto& chdr = hdr; foo(chdr); bar(chdr); baz(chdr);

Nikita Khomutov
Ну так если явно хочешь это зарестриктить, то прощ...

О чем я и писал несколькими сообщениями выше. Контролировать это придется вызывающему контексту. А если он с головой не дружит в момент вызова - не будет он эти const'ы кругом расставлять. Таким образом я вынуждаю лишний раз подумать со своей стороны (интерфейса вызываемого компонента), а не надеяться, что вызыватель (вполне может статься, что тоже я, только несколькими часами позже) станет во все эти const/non-const всматриваться. Не говоря уже о том, что один и тот же агрегат может потребоваться и с const и с non-const т.з. последовательно.

Sergey Anisimov
О чем я и писал несколькими сообщениями выше. Конт...

Ну и это нормально. Вызываемое API прямо говорит про свои контракты. Вызывающий контекст сам должен решать, какой уровень гарантий ему нужен. Если вызывающий контекст с головой не дружит, боюсь, тут ничто не поможет. Попытка подстелить в конкретном месте другую языковую конструкцию в предположении, что пользователь API плохо знаком с языком — приведёт к тому, в случае если пользователь действительно таков, что в другом месте будет демонстрировать точно такое же непонимание гарантий и контрактов.

Nikita Khomutov
Ну и это нормально. Вызываемое API прямо говорит п...

Вот как раз вот это и поможет. &hdr - пишем, hdr - не пишем. Попытка поменять местами приведет к ошибкам компиляции в обоих случаях. Опять же, я не претендую с этой своей идиосинкразией на статус какого-то стандарта. Речь шла о том, что семантика ссылок и указателей вполне себе кастомизируема, и, имхо, не может однозначно указывать на возможность передачи null'а соответствующим аргументом. На это как раз следует указывать явным способом: alias'ы (NullablePtr<Type>), атрибуты (если/когда будут), контракты (туда же), документация, в конце концов. От того, что некто не передаст null, скорее всего ничего не упадет. А вот в противном случае очень даже может.

Sergey Anisimov
Если нужна явная индикация того, что указатель мож...

Сергей, придумай себе аватарку, поставь... Естественно, это просьба

Ilya Zviagin
Сергей, придумай себе аватарку, поставь... Естеств...

Да, я вижу, так проще людей идентифицировать. Воткнул абстрактщину.

Egor Kulebyakin
где она?

А, извиняюсь, настройки приватности. Исправил.

Похожие вопросы

Обсуждают сегодня

я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
короче сгенерила мне эта штука код на ассемблере: struc string val { common local .value dq .value .value: if ~val eq db val end if db 0 } fo...
Vi Chapmann Chapmann
12
Всем привет! Массив вводится с клавиатуры, кол-во элементов неизвестно, поэтому я указал arr db 100 dup(?) С нахождением максимума проблем нет, а вот минимум почему-то всегд...
En Vind Av Sorg
11
Помогите, пожалуйста, делаю программу для для подсчёта корней квадратного уравнения, знаю, что есть куча недочётов, недоработок, но основная проблема в том, что почему-то при ...
NYC
13
#include <stdio.h> int main(void) { int n; scanf("%d", &n); int digits1[n] = {0}; int digits2[n] = {0}; я не могу таким образом заранее массив нулями заполнить?
Linus
12
в сях есть множество как в питоне? для удаление дубликатов
Linus
25
читать файл максимально быстро? странный вопрос))
zamtmn
53
я про форму записи. смысл указывать что 8 байтный регистр 8 байт?
Aiwan \ (•◡•) / _bot
10
Вроде бы вопрос уже заезжанный, но тем не менее У меня есть функция menu() которая выводит набор возможных действий, а затем спрашивает у пользователя что он хотел бы сделать....
David Golovatin
3
а как бы вылезти из ИО, что то типа IO -> Ether или в какую сторону смотреть ? что то туплю
Fedor
14
Карта сайта