Но это не является кодом на Rust. Напомню, что код на Rust не может содержать UB, поэтому это код на каком-то растоподобном псевдоязыке. В расте такой проблемы нет.
Спасибо повеселили. Код с UB не является кодом на С++. Корректный код на С++ не может содержать UB. Я ведь тоже так могу перефразировать.
Кстати гарантии для вызова unsafe они не в unsafe блоке содержатся. Если вы хотите разименовать указатель внутри unsafe блока Вы должны гарантировать что он валидный, а создан он мог быть вообще в абсолютно другом месте программы. Поэтому не всё так радостно, но от части ошибок защищает и при правильном подходе позволяет делать cвои safe api на основе unsafe инструкций.
Примеры вам привели. И да, пример, который вы придумали сами (когда объекты «живут» внутри другого объекта, при этом имеют так же ссылки и друг на друга) — тоже не редкость.
Кстати в расте так нельзя сделать совсем, и я думаю в том числе потому что нету этого провалила про порядок полей в структуре
std::optional как вариант или std::tie. Я не знаю, сам писал (немного) раньше в си стиле. Интересно как принято сейчас делать в плюсах, разве не затем придумали исключения и все остальные штуки поновее?
? Передача выходных значений через аргументы это же ближе к си чем к наворотам современных плюсов. Даже иногда предлагают использовать анонимные лямбды для этого дела. И что то мне кажется что после компиляции код будет такой-же.
Но ведь сейчас split() в многих языках
1) умеют не только строки а также другие контейнеры
2) и возвращают они итераторы
Т.е. на подобии ranges только ещё и в IDE методы выпадают.
Благодаря twinklede получилось сделать похожее на плюсах и boost::hana. Но в синтаксис языка это не очень вписывается. Если кратко то нам надо на каждую переменную новый тип это будет немного костыльно:
auto x = make<source_loc()>(rand());
auto y = make<source_loc()>(rand());
Теперь у икс и игрек разные типы и раные значения. Далее в hana мы можем работать с темплейтами и типами в них как с обычным структурами данных типа set, dict, etc. Например в типе переменной будет хранится ид и множество ид других переменных которым она равна. Т.е. например auto opt_z= x.equal(y) дает нам std::option в котором кроме null (при рантайм значении x!=y) могут быть две новые переменные x1, y1 в типах которых есть отметка о равенстве. После распаковки можно будет делать static_assert(is_equal(x1, y1)).
Попробовал что то подобное реализовать на расте, но без зависимых дженерик типов не получится. приходится пробрасывать все начальные параметры дженериков вручную наверх, и в самой верхней функции уже пяток а то и десяток праметров. Т.е. для серьёзных применений не годится.
ЕМНИП Там не всё так просто, в процедурном макросе доступно только тот кусок кода перед которым он стоит, а нам надо вытащить трейт который в аттрибуте макроса а с этим проблема.
На обычных макрос есть например такое https://github.com/chancancode/rust-delegate.
Спасибо повеселили. Код с UB не является кодом на С++. Корректный код на С++ не может содержать UB. Я ведь тоже так могу перефразировать.
Кстати гарантии для вызова unsafe они не в unsafe блоке содержатся. Если вы хотите разименовать указатель внутри unsafe блока Вы должны гарантировать что он валидный, а создан он мог быть вообще в абсолютно другом месте программы. Поэтому не всё так радостно, но от части ошибок защищает и при правильном подходе позволяет делать cвои safe api на основе unsafe инструкций.
Кстати в расте так нельзя сделать совсем, и я думаю в том числе потому что нету этого провалила про порядок полей в структуре
std::optional как вариант или std::tie. Я не знаю, сам писал (немного) раньше в си стиле. Интересно как принято сейчас делать в плюсах, разве не затем придумали исключения и все остальные штуки поновее?
а не лучше
? Передача выходных значений через аргументы это же ближе к си чем к наворотам современных плюсов. Даже иногда предлагают использовать анонимные лямбды для этого дела. И что то мне кажется что после компиляции код будет такой-же.
Да на самом деле бесит что примитивные типы ведут себя не так как нормальные классы. Почему конструктор по умолчанию не определен у int?
Но тем не менее, явное лучше не явного.
У меня нету, картинка из интернетов)
Неудержался
Но ведь сейчас split() в многих языках
1) умеют не только строки а также другие контейнеры
2) и возвращают они итераторы
Т.е. на подобии ranges только ещё и в IDE методы выпадают.
Благодаря twinklede получилось сделать похожее на плюсах и boost::hana. Но в синтаксис языка это не очень вписывается. Если кратко то нам надо на каждую переменную новый тип это будет немного костыльно:
Теперь у икс и игрек разные типы и раные значения. Далее в hana мы можем работать с темплейтами и типами в них как с обычным структурами данных типа set, dict, etc. Например в типе переменной будет хранится ид и множество ид других переменных которым она равна. Т.е. например
auto opt_z= x.equal(y)дает нам std::option в котором кроме null (при рантайм значении x!=y) могут быть две новые переменные x1, y1 в типах которых есть отметка о равенстве. После распаковки можно будет делатьstatic_assert(is_equal(x1, y1)).Попробовал что то подобное реализовать на расте, но без зависимых дженерик типов не получится. приходится пробрасывать все начальные параметры дженериков вручную наверх, и в самой верхней функции уже пяток а то и десяток праметров. Т.е. для серьёзных применений не годится.
Синтаксис непривычный, но фишка классная, надо вам писать статью про ФП в примерах.
ЕМНИП Там не всё так просто, в процедурном макросе доступно только тот кусок кода перед которым он стоит, а нам надо вытащить трейт который в аттрибуте макроса а с этим проблема.
На обычных макрос есть например такое https://github.com/chancancode/rust-delegate.
А прошивка станка который транизсторы на заводе делает тоже на раст?
с границами известными в compile-time легко, есть уже всякие библиотеки, может даже как часть буста, например https://www.boost.org/doc/libs/1_69_0/libs/safe_numerics/doc/html/tutorial/6.html.
Весь интерес в том чтобы это работало в рантайм, как Вы написали ниже.
Там если глянуть на все эти
impl Abc for Widgetто будет примерно то что math_coder выше предлагал.Всегда было интересно сколько щупалец у существ которым "удобно на высокоуровневом ФП"
А с двумя типами получится через Deref, типа множественное наследование? Хотя это более редкий случай.
Выглядит это ужасно.
clang выдаёт, gcc нужен флаг -Wsystem-headers потому что ошибка по сути там возникает.
Есть ещё -Wdelete-non-virtual-dtor который входит в -Wall и он должен ругаться на строчку с delete.