Потому что изначально template<> и существует для того, что-бы определить все параметры шаблона до сигнатуры. decltype() появился позже. Правда непонятно зачем тут decltype, ведь в С++ есть вывод типа возврата.
Ой, а чего же так? Адепт призвал братьев по вере, что-бы они мне гадили, при этом проигнорировал все свои нелепые тезисы с которым опозрился? Ой, адепт просто погулил private и кинул первую ссылку в гугле, но опозрился. Ой, а потом просто забил на ответ сославшись на то, что это враньё? Да неужели.
Методы (не просто отдельные функции) есть.
Нету.
Деструкторы есть. drop — это именно что детерминированно вызываемый деструктор, после которого столь же детерминированно вызываются деструкторы полей, а никак не «что-то типа finalize в жава».
Опять какая-то чушь. Зачем адепт ретранслирует нелепые тезисы пропаганды? Деструктор — это то, что привязано к времени жизни объекта. drop никакого отношения к этому не имеет. Это именно finalize из жавы.
Вся эта чушь про какой-то рекурсивный вызов для полей — это просто чушь. Она ничего не значит. И никакого отношения к теме не имеет.
ГЦ нет. (Давным-давно был, удалили в 2014-м, ещё до выхода первой стабильной версии Rust.)
Подождите, но неужели адепт опять врёт? Что же данный адепт невежества цитирует "раст изначально скриптуха с ГЦ", а потом мне отвечает, что ГЦ то был, но сплыл. Т.е. я прав, ведь я не сказал, что он сейчас с ГЦ.
Но это неважно, потому что даже сейчас эта скриптуха с ГЦ. Семантически там везде ГЦ. Просто адепты этой скриптухи не особо компетентны в вопросе, но я им помогу.
Зачем вообще нужен ГЦ? Ой, основная его задача — перекрёстные ссылки. Без этого достаточно и рефкаунта. Но постойте, но ведь раст-скриптуха не может в перекрёстные ссылки. Ой, а почему же?
Таким образом, данное ограничение в скриптухе просто позволяет выкинуть ГЦ и заменить его на рефкаунт. Но ведь пропаганда говорит адептам, что там нет ГЦ? На самом деле она врёт. Там есть ГЦ на rc, но с некоторыми фокусами.
Фокус заключается в следующем. Зачем вообще нужен счётчик? А счётчик нужен для того, что-бы была возможность существования двух ссылок. Но подождите, но ведь с этой скриптухи две ссылки существовать не могут.
Правильно, в этом и заключается фокус. Если ссылка только одна, то счётчик ненужен. Таким образом его можно заменить на, условно, статический счётчик.
Схема простая как топор. Данная скриптуха говорит своим адептам "страдайте за веру" и они страдают, руками проставляя все алиасы. В рамках данной схему любой школьник может написать примитивный статический анализатор.
Схема там простая как топор. В этой примитивной скриптухи есть только ссылки и агрегаты. Со ссылками проблем особо нет. Есть проблемы с агрегатами.
Но там работает следующая схема. Скриптуха говорит адептам "руками свяжи поле и объект", таким образом задача сводится к предыдущей. Т.е. агрегат со ссылкой на какой-то объект считается его алиасом.
А ну ещё есть функция. Эта скриптуха слишком примитивна и не может анализировать тела функций, поэтому адепты так руками проставляют алиасы. Таким образом ссылка за тело функции не может выйти. Если адепт захочет — он может вернуть её из функции, но тогда он обязан связать её со входом. Далее скриптуха понимает, что выход — алиас входа.
Соответственно, сам анализ простой как топор. Есть верхний объект — он создаётся. Далее все ссылки — ссылки. Там неважно копируются они или не копируются. Есть ли у них сторедж, либо нет. Это просто ссылки.
Соответственно, если в каком-то из блоков существует более двух ссылок — ссылки перестают быть мутабельными. Таким образом к ним попросту невозможно применить drop.
Далее, в том блоке(скоупе), где объявлен алиас/ссылка и если она одна — то по выходу из скоупа скриптуха вставляет там drop. Всё.
Т.е. это такая вариация rc статическая. Далее всё остальное — это unsafe-хаки. Т.е. рантайм.
И никаким боком раст не подходит под определение «скриптухи» (ни по достоинствам, ни по недостаткам).
Подходит. Всем.
Типы НЕ ссылочные: переменные являются стореджем, как в C++.
Нет, к тому же про ссылочные типы я ничего не говорил. Переменные не являются стореджами. Это семантически ссылки. Они всегда ссылки, даже если типизированы как T, а не как ссылка на T. Это базовое свойство скриптухи.
В жаве перегрузка есть, в том числе для конструкторов
Нет. То, что там есть — это мусор. Оно не применимо r описываемой мною функциональности.
статические методы для создания объектов там используются по совсем другим причинам (например, для возможности создания объекта производного класса — погуглите «фабричный метод»).
Опять чушь. Кстати, заметим как адепт уже забыл про всю ту чушь, что он нёс про супер-новшества ввиде статически методов в раст-скриптухе. А далее он где-то услышал про фабричные методы, но он опять сел в лужу.
То, что статические методы используются для фабричных методов никак не отменяет тот факт, что они используются для того, о чём писал я. Понятия не имеют зачем адепт несёт подобную чушь. Потому что "в том числе" не значит "только для".
Я ответил только на совсем наглую ложь с вашей стороны (чтобы другие читатели не поверили в неё на слово, а таки затратили пару секунд на гугление). Остальное оставлю без внимания, так как у высказываний настолько недобросовестных собеседников вес всё равно равен нулю.
Читаем как "я просто ретранслировал тезисы пропаганды, ответов никаких у меня нет". "я надеюсь на то, что табуны таких же фанатичных и некомпетентных братьев по вере набегут, заминусуют неверного и он перестанет мне писать".
Т.е. ноль равный нулю попытался что-то там поотвечать, но ничего не смог. Это норма для адептов данного учения.
Я вот не понимаю — откуда вы берёте все эти глупости?
В C, но не в C++.
Этого уже достаточно, зачем вы везде пихаете свою второсортную вторичную стриптуху? Что-то потом засыпаться?
К тому же, это так же работает и для С++. Но это не работает для сложных типов, но об этом позже.
Когда при принятии C++11 думали, как уменьшить число копирований, почему-то результатом стала move-семантика.
Полная и нелепая чушь, опять вы повторяете эту нелепость уже 10 лет. Вы не способны чему-то учиться.
move — это и есть копирование, и копирование всегда было таким. Другое дело, что в C++ с созданием raii копирование стало иметь другую семантику и копирование перестало быть копированием, коим оно является по умолчанию и коим является в си.
В связи с этим и появилось move, которая является тем самым копированием, которое было до раии и которое было в си.
А сейчас обнаруживается, что в 99% случаев-то на самом деле нужен destructive move (или relocation, как его сейчас называют).
Полная и нелепая чушь. Опять ретрансляция какой-то нелепой пропаганды какой-то нелепой скриптухи. "Trivially relocatable" не имеет никакого отношения к "destructive move" и прочей чуши.
Никакого "destructive move" в принципе не может существовать. Это костыль, который придуман в скриптухах типа раста. Где взята банальная сишная семантика, а далее примитивным статическим анализом поверх тысяч ограничений и ручного труда адептов — была реализована.
Т.е. в скриптухи нету никаких конструкторов, нету никаких деструкторов, нету никакого времени жизни. Кто угодно имеет полный доступ к объекту, как это было всегда в си.
К этому просто прикручена drop-семантика. Схема там проста — когда есть одна ссылка и область видимости кончается — срабатывает drop. Если ссылка не одна — мутировать объект нельзя. drop является мутацией.
Но всего этого не существует где-то за рамками примитивного статического анализатора. На уровне языка это просто структуры из си для которых где-то там вызывает drop. А так — они просто копируются как угодно. Как в си.
Вся эта чушь никак не работает в С++ и не может работать. Где у каждого объекта есть своё время жизни. Поэтому, вместо того, что-бы ретранслировать чушь не разбираясь в вопросе — лучше пойти и изучить букварь.
По поводу "Trivially relocatable" — его смысл в в следующем. Поды можно так же копировать как угодно, как в си. Но если мы навешиваем на этот под конструкторы/деструкторы — просто так копировать что-то уже нельзя. Семантика предполагает их вызов, за редкими исключениями.
Да вот, "Trivially relocatable" — это то, что позволяет сказать. "да, у меня есть конструкторы/деструкторы. Но я позволяю себя копировать, не вызывая их у копий, реализация объекта под хинтом предполагает это и никаких проблем не возникнет".
При этом нужно понимать, что это дырявый костыль. Его область применения крайне ограничена, в основном для всевдо-раишного кода. И подобные решения уже есть. Причём они куда лучше.
Если ещё проще. Подобная схема в рамках раии призвана куда-то наверх засунуть raii-объект, а далее использовать тот же объект как не-раии view. Но здесь можно просто использовать view. С++ это не примитивная скриптуха типа раста, где это невозможно сделать и приходится таскать оригинальные объекты.
Поэтому мы можем использовать raii-объекты как стореджи, а далее использовать view-объекты для доступа. Правда непонятно почему не подходят ссылки — почти везде для данного кейса их можно использовать. Я понимаю раст-скриптуху, где ссылки это муоср неудобный, но в С++ с этим проблем нет. Семантика, конечно же, сложная. Но на то он С++, а не примитивная скриптуха.
Поэтому если не хочется перемещать(читай копировать с вызовом не раишных конструктуоров/деструкторов) raii-объекты и есть гарантия, что изначальный объект не сдохнет быстрее копии. Можно просто сделать ptr_view, в который любой sp может каститься. А он pod — он уже копируется как нужно.
Хотя в комитете сидят люди далеко не глупые. Значит, со времён C++11 тенденции в языках программирования поменялись. Насколько я знаю, именно Rust привнёс концепцию destructive move в массы.
Relocatable — это понятие из C++. Аналог в Rust называется просто move и записывается как присваивание.
В этой скриптухи вообще никаких понятий нет. Там есть просто беспорядочное копирование чего угодно + все переменные семантически ссылки. move там больше костыль для примитивного статического анализатора.
Почему вам так трудно это понять. В скриптухе просто поды из сишки. Всё. Никаких конструкторов, дестркторов и времени жизни нет. В С++ это есть и уже поверх этого создано raii.
Скриптуха взяла raii из крестов, но оно там совершенно другого вида. Как бы попроще объяснить. В общем, если на примере с си. Это просто указатели, которые можно как угодно копировать. А потом магическим образом где-то компилятор вставить free.
Это примерно как cleanup, только чуть более импрувнутый, что в основном связано с примитивность самого языка и нагрузки на адептов.
Эта конструкция отменила бы копирование как поведение "по умолчанию".
Копирование и так поведение по умолчанию. У вас с этим проблемы большие. Есть язык — его логика совершенно иная. Не раишные. Базовая семантика языка другая, а раии это просто некая логика прикрученная сверху.
Ненужно это путать. И ненужно пихать это на уровень языка.
Но я особенно над этим не думал. Возможно, да, фигню сморозил.
У меня такое ощущение, как я уже говорил, что вы какие-то тайные "засланники". Вы не думая пишите какую-то чушь. Т.е. вы занимаете пропагандой мусорной скриптухи и враньём про то, что пишите.
Допустим, чушь про лямбды. Лямбды в раст-скриптухи — это паста []{} — базового синтаксиса из крестов и руби. Т.е. в скриптуха слишком примитивная — там ненужен список захватов. Точно так же в скриптухи слабая система типов — типов там вообще нет. Поэтому там и ненужны типы.
А вообще подобные примеры — позор:
auto add = |x, y| x + y;
auto dbl = |x| x * 2;
Я даже не буду говорить о том, что это синтаксический мусор и С++ не тот язык, который помойка. Так же, С++ является языком, а не примитивной скриптухой. Поэтому такой мусор в С++ вообще ненужен.
Не надо фантазировать. В расте полноценные пользовательские типы данных с инкапсуляцией состояния, методами и деструкторами.
Нет, очевидно. Там голые структуры из llvm(читай си). Никаких методов и деструкторов нет. К тому же, заметим, что я не говорил ничего про деструкторы, но адепт уже начал про них что-то рассказывать? Почему? Правильно — он не читал, не думал — он просто ретранслирует пропаганаду.
Есть только drop, который не деструктор. Это что-то типа finalize в жава. Раст это изначально скриптуха с ГЦ, к которой просто накрутили костылей.
Никаких методов нет — есть просто отдельные функции. Перегрузки нет, поэтому взятая из C++-перегрузка превращена в трейты, которые по-сути являются костылями/сахором поверх перегрузки.
Никаких прав доступа, наследования и прочего — нет, очевидно. Инициализаторов полей нет, конструкторов нет. Есть просто списки инициализаций из си.
Единственное, что их роднит с «голыми структурами (читай си)» — тривиальная перемещаемость
Роднит их то, что это это и есть структуры си. А тривиально перемещаются они так же, как подобные структуры в C/С++.
(от которой, если очень нужно, можно уйти, спрятав объект за Pin-ом).
Это уже костыль. В связи с тем, что объекты в расте беспорядочно копируются, потому как по природе это скриптуха с ГЦ. Все типы ссылочные, переменные не являются стореджем как в С/С++.
Далее это вызвало проблему, когда для реализация asyn ансейф-хак падал, потому как нужно было брать ссылки, которые умирали.
И слово struct, которым (наряду с enum) они объявляются.
Опять же, не только.
Права доступа есть.
Это не права доступа. Это костыли из модулей, о которых я ничего не говорил. Я говорил про права доступа для полей.
Наследования нет, но есть реализация интерфейсов (trait-ов) и композиция, которые решают те же задачи более изящно.
Опять же, чушь. Ничего они не решают. Ненужно в ответ мне ретранслировать пропаганду локальную — она мне не интересна.
Трейты — это нахлабучка поверх перегрузки. Она никак не влияет на структуру.
Конструкторов нет, поскольку в отсутствие традиционного наследования задача инициализации объекта корректнее
Опять пошла пропаганда второсортная. Ещё раз, меня не волнуют сектантские лозунги и за аргументацию они не считаются.
Дополнительные возможности — это следствие. Основное свойство конструктора — это создать класс функций, которые именно создают объекты. А дополнительные возможности — это вторично.
и гибче решается функцией (без параметра self), возвращающей объект.
Нет, очевидно. Опять мы видим сектантские лозунги. Никакого гибче нет — это просто отдельные функции инициализации из си. То, что было тысячи лет до того, как появились конструкторы.
Единственная разница, что в этой скриптухе эта функция не просто валяется в глобальном скоупе, а диспатчится по имени. Это типичная инициализация через статические методы, привет жава, привет 95.
Но в основном они нужны потому, что в данной скриптухи нет перегрузки. В жаве так же, поэтому там так же используются статический методы для не-стандартных инициализаций. Очевидно, что это мусор. Непонятно кто, что и куда инициализирует.
В тех же условных наследниках жавы с нормальным дизайном, допустим dart, эта проблема решается именованными конструкторами.
В такой функции можно вычислить значения всех полей до создания объекта
Пошло полное повторение тезисов из методички, которая оправдывает дыры в дизайне этой скриптухи. Насколько же это нелепо.
Всё это ничего не значит. Тут адепты немного перепутали реальность. Пропаганда им внушает, что их реалии — это что-то новое, но нет. Это 70 год. Самый примитив. Поэтому, если каким-то чудом я стану адептом этих лозунгов — я всегда могу использовать статические методы.
что полностью исключает саму фазу инициализации (в течение которой объект находится в нецелостном состоянии, но виден конструктором и вызываемыми из него методами)
Мусорные лозунги. Это было в 70 году в си. Это ничего не значит. Смысл инициализации именно в том, что конструктор и есть атомарный инициализатор.
а также из неё можно вернуть нечто более сложное, чем просто инициализированный объект (например, монаду вроде Result или Option).
Всё это нужно в скриптухи, в нормальном языке есть исключения. Я уже давно жду, что-бы какой-то адепт мне это сказал. Посмотрим, получится в этом раз.
К тому же, от создания объекта — мне нужен объект, а не мусор. К тому же, зачем мне перечислять примитивную чушь? Я понимаю, что пропаганда убедила адептов, что это какие-то новшества, но нет. Это то, что существовало ещё до рождения данного адепта.
Основания. Хотя глупо это спрашивать — Trivially relocatable — это базовое свойство всего в си. Когда там это было никакого раста в принципе не существовало, но в любом случае я жду оснований. Да и никаких понятий "relocatable" в расте в принципе нет — там голые структуры взятые из llvm(читай си).
Т.е. нет никакие конструкторов, нету наследования, прав доступа, инициализаторов и прочего.
Было бы круто ещё иметь короткие не-копирующие объявления переменных:
DMA_SxCR_DIR_0 не перечисление, это просто дефайн в CMSIS. Допустим, мы из них делаем перечисление и тогда валидацию на уровне enum можно делать, как вы предлагаете. Но это единый enum на регистр, что мешает сделать названия понятнее, по типу direction::to_periph или memory_size::byte16. Мелочь, а неприятно.
Ну дак и в вашем решении всё тоже самое. У вам такие же енумы.
Зачем писать в несколько регистров? Для унификации интерфейса. Я, как пользователь периферии, не очень то хочу помнить в какой конкретно регистр устанавливается определенное значение.
Не в этом дело. Дело в пересечении. У вас один енум на двух регистрах. Зачем одно и тоже значение писать сразу в два регистра? Это какая-то общая конфигурация? Как оно должно работать.
Тоже самое непонятно каким образом смешивать разные енумы? Зачем в разных енумах то, что потом смешивается? За счёт чего достигается безопасность?
Насколько я могу могу понять — разделение на разные енумы — это типа костыль для "понятных названий"? Опять же, зачем здесь енумы?
Хороший же интерфейс как раз, позволяет меньше задумываться о низкоуровневой реализации.
Это всё крайне сомнительно. Вы как-то изначально всё неправильно делаете. Зачем использовать данные в качестве флага?
Интерфейс — это интерфейс. В нём не должны торчать какие-то данные, кишки, енумы и прочее. Особенно если вы хотите constexpr. И какой-то реальной безопасности.
В общем я так и не понял что вам нужно. Дайте ссылку ну C++-api — хоть посмотрю.
Сразу видно, что с++ подход более читаем, и, поскольку каждая функция принимает конкретный тип, нельзя ошибиться. Си подход не проверяет валидность данных, это ложится на плечи программиста.
Во-первых здесь ошибка. Если CR и все флаги — enum class cr, то никакой проблемы нет. Проблема здесь только для обычного енума. Таком образом на С++ левый вариант так же проверяется.
Всё, и никаких проблем. Причём ide при написании | сама подсказывает нужные флаги.
Далее вы так и не ответили на вопрос — зачем записывать сразу в несколько регистров. Я вижу тут только дыру в реализации. Я не особо разбираюсь в мк"ашках и видел их последний раз много лет назад. Да и потолком моего знакомства было ваяние генератора сигналов.
Теперь вернёмся к примеру на С++. Вы утверждали, что там всё проверяется. Но когда я вам показал точно такой же интерфейс, только с РЕАЛЬНЫМ компилтайм-вычислением флагом — вы мне сказали "там ничего не проверяется". Вы это так же не прокомментировали.
Непонятно, что вам там непонятно. Флаги заменяются на вызов методов. Сам флаг передаётся через тип. Ничего невозможно никуда передать, точно так же как это сделано в примере выше — у вас попросту нет будет нужных методов.
Если не стоит задача сделать реальный constexpr — достаточно просто смены интерфейса. Нам нужно вначале составлять значение, а потом уже писать. Делается точно так же как в с маской — я показал.
Если хочется и аргументы передавать как constexpr, то это так же без проблем делается. Вариантов много. Передавать через nttp.
Так:
template<enum cr arg> auto f() {}
Можно использовать уже value-подход.
template<auto value> struct enum_t: std::integral_constant<decltype(value), value> {};
template<auto value> auto enum_v = enum_t<value>{};
template<enum cr value> auto f(enum_t<value>) {}
f(enum_v<cr::DMA_SxCR_DIR_0>);
Можно так, если нужно принимать не только cr.
auto f(auto flag) {
static_assert(std::is_same_v<decltype(flag()), enum cr>);
}
template<auto flag> auto f(enum_t<flag>) {
static_assert(std::is_same_v<decltype(flag), enum cr>);
}
Первое здесь правильный value-подход. Вытаскивание типа через nttp — это такой больше костыль.
Можно вообще отказаться от enum. И сразу определять флаги в виде привычном для value-подхода.
Повторяю ещё раз. Я не увидел какой-то валидации сверх enum class и его достаточно. Так же здесь нет constexpr, о чём я уже сообщал выше. Проблему показанного С++-интерфейса можно решить просто отделением билдера.
Единственный функционал какой здесь — это диспатч по регистрам в зависимости от типа enum"а. Но я считаю это не фичёй, а багом. Вы не прокомментировали это.
Ну попробуйте реализовать без списка типов обобщённо.
Причём тут список типов?
Я с удовольствием почитаю, а то только можно да можно, без конкретики.
Я показал как, тот же ranges показал как — там 1в1 первый вариант.
Ту ссылку, что вы привели не имеет никакой валидации
Очевидно, что она есть.
а чтобы её прикрутить, на скорый взгляд, придётся делать всё тоже самое.
Причём тут тоже самое? Речь ни о реализации, а об интерфейсе для пользователя. Это какие-то непонятные мне манёвры.
Как минимум надо будет хранить в constexpr контексте информацию о регистрах и как они связаны с перечислениями
Вы не понимаете как это работает. У вас там никакого constexpr-контекста нет. То, что вы натыкали туда constexpr — это ничего не значит. Смысл подхода, который вы повторили именно в том, что-бы иметь контекст вне контекста.
https://godbolt.org/z/dTmqgt — это было предсказуемо. Реально там ничего не constexpr, для чего не определяется constexpr-контекст явно. А он там определяется только в if constexpr и всё, может где-то ещё.
Потому как аргумент лямбды не constexpr, даже если op() выполняется в constexpr-контексте.
при этом количество этих регистров и перечислений в обобщённом алгоритме неизвестно.
С чего вдруг оно неизвестно? Оно не может быть неизвестно. Это, опять же, непонятные мне манёвры и попытка придумать новую задачу, что-бы оправдать неудачный подход.
К тому же, если он неизвестный, что что делает какая-то лапша в Register1, в static constexpr void set(Ts...args) и остальных местах? Т.е. это уже попытка реализовать ту самую "известно", причём руками. Причём лапшой.
Здесь просто реализована функция set, которая непонятно что, как и куда записывает. Это не реализация интерфейса показанного выше. Это просто форчи + фильтр.
А там посмотрим, какой подход лаконичнее и понятнее.
Дак у вас нет никакого подхода. Вы не реализовали то, что показывали выше. Вы реализовали именно сишный вариант.
Он тайпчекается, в enum class — не записать не те значения. Этой фишка есть по умолчанию.
У вас осталось только одно — это диспатч по типу значения в регистр. Это просто побочный эффект и я не вижу его выше. Да и не факт, что он вообще адекватен задаче.
У меня нет явной связи с регистрами, таким образом непонятно на каком основании невозможность задать значение общего енума для одного конкретного регистра. Это очень похоже на дыру в реализации.
В общем, вы как-то более подробно опишите то, что вам нужно. Я вижу только аналог си-интерфейса. Я вижу попытку сделать типобезопасный enum, но он уже есть. Я вижу какую-то непопонятную логику с записью в два регистра сразу. Которой управлять нельзя.
Опишите — я напишу реализацию. Пока что я ничего не понимаю.
или нужно будет переопределять оператор | для каждого параметра и сразу навскидку я не соображу как это провернуть.
Очевидно, что всё нужно переопределять.
Забавно, что мой подход назвали из джавистким
Я объяснил почему и что.
и сами же приводите пример ооп-паттерна, которые в джаве на уровне языка есть.
Я привожу пример доступный. К тому же здесь нету никакого нового паттерна — это паттерн уже был изначально. Я просто разделил конфигурацию его.
А из жавы там не паттерн, а подход.
Опять же билдер придётся писать для каждой периферии для валидации.
Опять же нет. Он такой же, как и базовый. Если набор методов зависит от some_stream — это так же не проблема. Его/его тип можно использовать для создания билдера.
Хотя может и можно обобщённый алгоритм тоже написать. Можно подумать.
Можно.
Плюс моего подхода в том, что алгоритм написан один раз, протестирован и далее просто нужно выполнить концепт работы с перечислениями и периферией.
Там так же всё написано один раз. В к тому же потерять всё и игнорировать этот факт — это плохой подход.
Может и лучше.
Именно лучше. У первого варианта нету никаких преимуществ — одни недостатки.
Суть поста была в том, чтобы показать, что со списками типов стало работать куда проще и можно решать задачи, которые раньше были не по силам среднестатистическому разработчику. Детали реализации не так важны.
Ну дак в этом проблема. Ведь смысл то не в списке типов, а в разделение состояния на constexpr в шаблонах(в типе) и на рантайм(в данных).
А задача безопасности — быть незаметной. Страдать за веру — это не подход С++.
Ах да, код не работает в шланге из-за "как попало без захвата". [=]
Сразу видно, что с++ подход более читаем, и, поскольку каждая функция принимает конкретный тип, нельзя ошибиться.
Для меня это не очевидно, да и это не С++-подход. Это скорее си с классами подход.
Но с++ подход не бесплатен. Фактически, каждая функция имеет своё обращение к регистру, в то время как на си сначала собирается маска из всех параметров на этапе компиляции, так как это всё константы, и записывается в регистр разом.
Это проблема си с классами/жава подхода. Да даже проблема не их, а просто неправильного api.
Желательно, чтобы это не сильно отличалось от уже привычного с++ подхода.
А здесь всё теряется. Удобство использования. ide асист не даёт, отдельно сеттеры не валидируются и прочее. Ошибку плюёт сразу в вариадик-лапшу, а не в отдельные функции. Никакие флагсеты не запишешь. Нужно костылить дополнительно то, что ниже.
Поэтому правильными подходами будет два подхода.
some_stream.set = inc_memory | size_memory(DataSize::word16) | size_periph(DataSize::word16) |enable_transfer_complete_interrupt;
//Семантика будет так же
//либо перенести билдер туда же:
some_stream.set = set_builder().inc_memory().size_memory(DataSize::word16).size_periph(DataSize::word16).enable_transfer_complete_interrupt();
https://godbolt.org/z/hs9BwL — второй пример элементарно делается. Правда там должны быть типы, а не рантайм-фигня.
Второй лучше тем, что лучше асист. Если там много всяких флагов — с первым запутаешься. Но первый лучше тем, что как и обычный | записывать наборы флагов в переменные.
Хотя и билдер это позволяет сделать, но менее универсально. Хотя можно реализовать какой-то метод .extend(other)/+/| вставлять даже в середину/конец, а не только начало.
Правило простое. Все изменения производит на уровне типов, тогда получаем constexpr-контекст везде. Рантайм-параметры таскаем как значения.
Про:
struct {} constexpr not_set;
template<typename> constexpr auto enum_traits = not_set;
template<> constexpr auto enum_traits<Enum1> = 0b00111;
template<> constexpr auto enum_traits<Enum2> = 0b11000;
template<> constexpr auto enum_traits<Enum3> = 0b00111;
template<> constexpr auto enum_traits<Enum4> = 0b00111;
Уже сказали.
Наследовать так же лучше как-то так: : enum_list<Enum1, Enum3> Тогда все эти магические типы пропадут.
Методичка потекла. Я не обязан доказывать отсутствие чего-то — это задача адепта доказывать присутствие. В данном случае важности.
Ссылка была выше. Если она вам не нравится, то вопросы не к ней, а к вам.
Ещё раз ссылку, к тому же там говорилось не только о ссылке.
То есть, вы согласны с тем, что не знаете C++? Отлично, наконец-то.
С чего вдруг? Я лишь доказал в том, что мой оппонент ваяет примитивное легаси-говно, при этом заявляя себя как эксперта и заявляя то, что хаскель может заменить С++. При этом, почему-то легаси-дерьмо ваяет на плюсах.
Тут явные проблемы с логикой и методичкой.
Аналогично: если вам не нравятся доказательства, то вопрос не к доказательствам, а к вам.
УБ нет. Аналогично: если вам не нравятся доказательства, то вопрос не к доказательствам, а к вам.
Основания.
Задача адепта предоставлять доказательства заинтересованности.
Не, сорян, это так не работает. Не получится специально не гуглить, не ходить по ссылкам, а вместо этого закрыть уши и глаза и громко кричать «нету этого врёти адепты методички поломался задачу дал».
Нет, адепт не дал никакой ссылки. Адепт просто болтает. Всё, что болтает и на что нет пруфов и обоснований(хоть каких-то) — балабольство. Никто не просит болтуна идти и в стандарт — он всё ровно ничего не знает и не осилит его прочитать.
Нужно хотя-бы показать основания. Почему это так, а не иначе. Привести хоть какие-то доводы, а не бла-бла я так сказал.
А какие требования предъявляются тут?
Такие, почему адепт ваяет примитивное легаси-говно на С++, а не бороздит космос на хаскеле.
Которая не имеет никакого отношения к обсуждаемому предмету.
Имеет. Основания. Я их предоставил. Болтун нет.
Я воспроизвёл. Одним из наиболее удобных вариантов (т. к. там UB).
Во-первых адепт не доказал наличия там УБ и его нет. Во-вторых УБ ничего не значит и никого не интересует и никак болтуна от ответа не освобождает.
К тому же, болтун даже тут сел в лужу. Нельзя УБ как-то трактовать. Опять болтун где-то услышал какую-то чушь и повторяет.
Напоминает фанатов Go, у которых и дженерики-темплейты ненужно.
Если это неважно, зачем адепт об этом пытается сообщить?
Опять «вывсёврёти». Ну вы бы хоть погуглили бы прежде чем так позориться.
Мне ненужно ничего гуглить. Я сказал — адепт поломался. Задача адепта скриптухи доказывать то, что в ней что-то есть. Я не занимаюсь поиском херни.
Задача показана — задача адепта воспроизвести, а не болтать.
Которую до сих пор даже в C++ не завезли, ага.
Опять какая-то чушь. Опять адепт пытается нести херню вида "почему самолёты летают так медленно — я вот вчера своё корыто затюнил в 2 раза". Потому что, адепт, это разные миры. То, что происходит в твоём колхозе — ничего не значит. Они не соответствует тем требованиям, что предъявляются тут. А то, что запросы у тебя нулевые — это лишь следствие твоих примитивных запросов.
То есть, код с вас, а отвечать должен за это я?
Какой код? Отвечать нужно за болтовню. Я дал задачу на демонстрацию диспатча и инлайна. Ваша задача воспроизвести. Не сможете — ты сели в лужу.
Это уже совсем трэш пошёл. Вот хочу я считать XML с описанием схемы сообщений, или HTML с ещё чем-то, да мало ли, что мне в C++ делать?
Я сразу сказал, что адепт начнёт эту историю про скриптуху. Никакой хмл, хтмл и прочие скриптушное нечто — ненужно.
С++ куда мощнее и выразительнее для описания любых данных, текстовый мусор — удел скриптухи.
Единственное, почему С++ используется там, где есть этот мусор — это то, что скриптуха не может работать быстро и надёжно. Поэтому приходится приходить королю и разруливать.
А так, это задачи недостойные С++. А даже если кому-то это понадобиться — это реализуется за пол дня, как я уже говорил. Правда никому это ненужно, хотя может кому-то и нужно и там это уже есть.
Ух ты, и получили то (нифига не стандартизованное, правда)
Нет, кстати, здесь можно заметить типичную неадекватную логику.
что было в никому не нужном скриптушном хаскеле уже лет 17 (template haskell — ровно про это, чтобы обычными функциями оперировать представлением исходников).
Подождите, но ведь оно тоже не стандартное. И что, поломалось методичка?
К тому же, это полная чушь. Ничего этого в этой скриптухи нет. Адепт врёт. А колхоз-интроспекция уровня начальной школы, либо eval — этому уже лет 30 в скриптухи.
Опять адепт пытается кичиться общими(бесплатными) свойствами скриптухи выдавая их за свойства отдельной скриптухи.
Кстати, как насчёт того, чтобы с вашей макрухой считать файл и на базе него сгенерировать какие-то данные или типы? Смогёте?
Во-первых адепт не может мне рассказывать про смогёт, пока не ответит за прошлой смогёт.
Во-вторых — файлы это уровень скриптухи. В не скриптухи существует только код. Всё код. С файлами в пхп.
Это, кстати, типичный подход адептов скриптухи. Прибегают с какой-то ахинеей и начинают её требования. Сама ахинея ничего не стоит. Чтение файла в блоб реализуется за максимум те же пол дня. Почему никто не реализовал? Да потому что это нахрен никому здесь ненужно.
Кстати, это же методичка про интернет. Я потом линкану предыдущие рассуждения данного адепта. Там тезисы того же уровня, а может даже выше.
В общем, поверх языка всегда надстраивались всякие левые правила для внешних инструментов, в том числе компиляторов.
Вначале это были просто всякие хинты в комментах. Но хинты на то и хинты, что они чисто декларативны. Это мета-аннотации.
Всякие макро-расширения уже позволяли производить логику. Ну вот в раст перепастили такой отдельный, левый макро-язык. Это вообще не раст.
Для языка это что-то типа комментов. Типичный макропроцессор из си. Правда в си он был изначально отдельной программой, но сейчас он по-сути часть компилятора.
И этот отдельный язык может инлайнится в файлы с раст-кодом. Это допустим как инлайнинг тестов.
Т.е. это код, код на внешнем языка, который исполняет компилятор. Это расширение логики компилятора. И семантически и с ТЗ реализации.
В расте объектная модель примитивная как топор. Там есть только структуры как в си(из llvm). Больше ничего нет. Нет методов, нет областей видимости, наследования и всего того, что и делает интроспекцию сложной.
https://godbolt.org/z/BMGSSU — это, конечно, вещь несоизмеримо более мощная. Но пример и подход тот же. Плагины писать сложно — поэтому реализуется dsl для удобной го написания правил. Но по-сути это расширение.
Я не удивлюсь тому, что кто-то уже реализовал инлайнинг этих правил в С++-атрибуты/комменты.
Так же, это на тему того о чём я говорил. Что делает это за пол дня. Из этого выхлопа можно сразу генерировать адептеры, а далее язык всё может сделать сам.
Да и, как я уже говорил, существует реализация рефлексии/интроспекции для С++. Реализовать там поиск поиск поля с нужным типом достаточно просто: https://godbolt.org/z/nGjMro
И это не плагин, это не макросня и не внешний язык. Это именно С++ код. Это такая же функция, которая вызывает обычные функции, получает обычные результаты. И может на порядки больше, чем убогая скриптуха/макросня из скриптухи.
Так как в общепринятом смысле слова "адептом" чего бы то ни было я не являюсь
Любой адепт уверяет всех, что он не адепт. Это стоит ноль.
а используемое Вами значение слова мне неизвестно, первое высказывание для меня не имеет смысла. Более того, с большой долей вероятности оно не имеет смысла также и для остальных присутствующих в этом обсуждении, кроме Вас.
Оно имеет вполне очевидный смысл. Просто адепты пытаются казаться какими-то уникальными и независимыми. На самом деле у них одна методичка на всех, они все из одной секты. Там достаточно пойти полистать комменты.
Если Вас не волнует, как называется какое-то явление в той среде, в которой оно существует, не стоит доказывать, что оно называется именно так, как Вы сказали, а не иначе ("это не макрос, а плагин компилятора").
Ещё раз, явление в какой-то среде называет так только в рамках среды. Вы опять палитесь. То, что вы думаете, что ваша среда(читай учение о поклонение очередной скриптухи) может диктовать условия всем — это типичный сектантский паттер поведения.
Поэтому, я могу это называть как хочу. У меня есть тому основания, которые вы проигнорировали. У вас же никаких оснований нет, кроме ссылок на методичку какой-го учения.
Внутреннее противоречие (в данном случае — "мне это неважно, но я буду это доказывать") не помогает ни в каком случае, кроме намеренного введения в заблуждение.
Опять адепт пытается рассказывать о том, что несоблюдения догматов какой-то секты автоматически определяет твои суждения не верными.
Читать любое высказывание нужно в первую очередь дословно.
Не нужно.
Иначе есть большая вероятность додумать за собеседника то, чего он заведомо не мог предположить.
Есть вероятность того, что собеседник севши в лужу начнёт придумывать своим словам новые смыслы.
Если, конечно, Вы не являетесь обладателем паранормальных способностей.
А можно было сразу прямо сказать, что Вы не согласны с официально принятой в соответствующей среде терминологией (и поэтому procedural macros в Rust — это для Вас не макросы)?
Очередной адепт скриптухи начал отождествлять себя с какой-то официальной принятой терминологией.
Хотя на самом деле он ссылается на догматы локальные своей веры, т.е. конкретной скриптухи. В данном случае раста.
Во-первых, скриптуха сама определяет что и как называть. Никакой "официально принятой терминологии нет". Во-вторых — меня не должно волновать то как адепты очередной скриптухи что-то называют. Это должно волновать только других адептов.
Это настолько удивительно, что каждый адепт очередной скриптухи пытается убедить кого-то в том, что этот кто-то должен принять его веру?
Ну и вообще в аналогичных случаях сразу раскрывать свою мысль. Меньше же потом объяснять придётся.
Читать нужно — "я сел в лужу и попытался нелепо оправдаться", типа "я сразу не понял, что ты дурак, но ты дурак".
Это все, конечно, так, но никак не противоречит тому, что я написал.
Там нету отсылки на то, что решение не полноценно. О чём я и сообщил. Т.е. оборачивать надо и ваши енумы туда попросту не засунуть. К тому же, я нигде не говорил, что что-то чему-то там противоречит. Я лишь сообщил, что упомянутое решение не соответствует описанию. Всё.
У этого решения есть еще два недостатка — первый это то, что в исполняемый файл попадают строки вида «constexpr auto f() [with auto v = Color::RED]» целиком, из-за чего бинарник разбухает. Из этого вытекает второй — имя дергается как subview от этой строки, и оно получается не нуль-терминировано.
Не вижу проблемы ни в первом ни во втором случае. В любом случае это просто детали реализации — https://godbolt.org/z/RzFTL5 — вот, никаких строк нет.
Потому что изначально template<> и существует для того, что-бы определить все параметры шаблона до сигнатуры. decltype() появился позже. Правда непонятно зачем тут decltype, ведь в С++ есть вывод типа возврата.
Ой, а чего же так? Адепт призвал братьев по вере, что-бы они мне гадили, при этом проигнорировал все свои нелепые тезисы с которым опозрился? Ой, адепт просто погулил private и кинул первую ссылку в гугле, но опозрился. Ой, а потом просто забил на ответ сославшись на то, что это враньё? Да неужели.
Нету.
Опять какая-то чушь. Зачем адепт ретранслирует нелепые тезисы пропаганды? Деструктор — это то, что привязано к времени жизни объекта. drop никакого отношения к этому не имеет. Это именно finalize из жавы.
Вся эта чушь про какой-то рекурсивный вызов для полей — это просто чушь. Она ничего не значит. И никакого отношения к теме не имеет.
Подождите, но неужели адепт опять врёт? Что же данный адепт невежества цитирует "раст изначально скриптуха с ГЦ", а потом мне отвечает, что ГЦ то был, но сплыл. Т.е. я прав, ведь я не сказал, что он сейчас с ГЦ.
Но это неважно, потому что даже сейчас эта скриптуха с ГЦ. Семантически там везде ГЦ. Просто адепты этой скриптухи не особо компетентны в вопросе, но я им помогу.
Зачем вообще нужен ГЦ? Ой, основная его задача — перекрёстные ссылки. Без этого достаточно и рефкаунта. Но постойте, но ведь раст-скриптуха не может в перекрёстные ссылки. Ой, а почему же?
Таким образом, данное ограничение в скриптухе просто позволяет выкинуть ГЦ и заменить его на рефкаунт. Но ведь пропаганда говорит адептам, что там нет ГЦ? На самом деле она врёт. Там есть ГЦ на rc, но с некоторыми фокусами.
Фокус заключается в следующем. Зачем вообще нужен счётчик? А счётчик нужен для того, что-бы была возможность существования двух ссылок. Но подождите, но ведь с этой скриптухи две ссылки существовать не могут.
Правильно, в этом и заключается фокус. Если ссылка только одна, то счётчик ненужен. Таким образом его можно заменить на, условно, статический счётчик.
Схема простая как топор. Данная скриптуха говорит своим адептам "страдайте за веру" и они страдают, руками проставляя все алиасы. В рамках данной схему любой школьник может написать примитивный статический анализатор.
Схема там простая как топор. В этой примитивной скриптухи есть только ссылки и агрегаты. Со ссылками проблем особо нет. Есть проблемы с агрегатами.
Но там работает следующая схема. Скриптуха говорит адептам "руками свяжи поле и объект", таким образом задача сводится к предыдущей. Т.е. агрегат со ссылкой на какой-то объект считается его алиасом.
А ну ещё есть функция. Эта скриптуха слишком примитивна и не может анализировать тела функций, поэтому адепты так руками проставляют алиасы. Таким образом ссылка за тело функции не может выйти. Если адепт захочет — он может вернуть её из функции, но тогда он обязан связать её со входом. Далее скриптуха понимает, что выход — алиас входа.
Соответственно, сам анализ простой как топор. Есть верхний объект — он создаётся. Далее все ссылки — ссылки. Там неважно копируются они или не копируются. Есть ли у них сторедж, либо нет. Это просто ссылки.
Соответственно, если в каком-то из блоков существует более двух ссылок — ссылки перестают быть мутабельными. Таким образом к ним попросту невозможно применить drop.
Далее, в том блоке(скоупе), где объявлен алиас/ссылка и если она одна — то по выходу из скоупа скриптуха вставляет там drop. Всё.
Т.е. это такая вариация rc статическая. Далее всё остальное — это unsafe-хаки. Т.е. рантайм.
Подходит. Всем.
Нет, к тому же про ссылочные типы я ничего не говорил. Переменные не являются стореджами. Это семантически ссылки. Они всегда ссылки, даже если типизированы как T, а не как ссылка на T. Это базовое свойство скриптухи.
Нет. То, что там есть — это мусор. Оно не применимо r описываемой мною функциональности.
Опять чушь. Кстати, заметим как адепт уже забыл про всю ту чушь, что он нёс про супер-новшества ввиде статически методов в раст-скриптухе. А далее он где-то услышал про фабричные методы, но он опять сел в лужу.
То, что статические методы используются для фабричных методов никак не отменяет тот факт, что они используются для того, о чём писал я. Понятия не имеют зачем адепт несёт подобную чушь. Потому что "в том числе" не значит "только для".
Читаем как "я просто ретранслировал тезисы пропаганды, ответов никаких у меня нет". "я надеюсь на то, что табуны таких же фанатичных и некомпетентных братьев по вере набегут, заминусуют неверного и он перестанет мне писать".
Т.е. ноль равный нулю попытался что-то там поотвечать, но ничего не смог. Это норма для адептов данного учения.
Я вот не понимаю — откуда вы берёте все эти глупости?
Этого уже достаточно, зачем вы везде пихаете свою второсортную вторичную стриптуху? Что-то потом засыпаться?
К тому же, это так же работает и для С++. Но это не работает для сложных типов, но об этом позже.
Полная и нелепая чушь, опять вы повторяете эту нелепость уже 10 лет. Вы не способны чему-то учиться.
move — это и есть копирование, и копирование всегда было таким. Другое дело, что в C++ с созданием raii копирование стало иметь другую семантику и копирование перестало быть копированием, коим оно является по умолчанию и коим является в си.
В связи с этим и появилось move, которая является тем самым копированием, которое было до раии и которое было в си.
Полная и нелепая чушь. Опять ретрансляция какой-то нелепой пропаганды какой-то нелепой скриптухи. "Trivially relocatable" не имеет никакого отношения к "destructive move" и прочей чуши.
Никакого "destructive move" в принципе не может существовать. Это костыль, который придуман в скриптухах типа раста. Где взята банальная сишная семантика, а далее примитивным статическим анализом поверх тысяч ограничений и ручного труда адептов — была реализована.
Т.е. в скриптухи нету никаких конструкторов, нету никаких деструкторов, нету никакого времени жизни. Кто угодно имеет полный доступ к объекту, как это было всегда в си.
К этому просто прикручена drop-семантика. Схема там проста — когда есть одна ссылка и область видимости кончается — срабатывает drop. Если ссылка не одна — мутировать объект нельзя. drop является мутацией.
Но всего этого не существует где-то за рамками примитивного статического анализатора. На уровне языка это просто структуры из си для которых где-то там вызывает drop. А так — они просто копируются как угодно. Как в си.
Вся эта чушь никак не работает в С++ и не может работать. Где у каждого объекта есть своё время жизни. Поэтому, вместо того, что-бы ретранслировать чушь не разбираясь в вопросе — лучше пойти и изучить букварь.
По поводу "Trivially relocatable" — его смысл в в следующем. Поды можно так же копировать как угодно, как в си. Но если мы навешиваем на этот под конструкторы/деструкторы — просто так копировать что-то уже нельзя. Семантика предполагает их вызов, за редкими исключениями.
Да вот, "Trivially relocatable" — это то, что позволяет сказать. "да, у меня есть конструкторы/деструкторы. Но я позволяю себя копировать, не вызывая их у копий, реализация объекта под хинтом предполагает это и никаких проблем не возникнет".
При этом нужно понимать, что это дырявый костыль. Его область применения крайне ограничена, в основном для всевдо-раишного кода. И подобные решения уже есть. Причём они куда лучше.
Если ещё проще. Подобная схема в рамках раии призвана куда-то наверх засунуть raii-объект, а далее использовать тот же объект как не-раии view. Но здесь можно просто использовать view. С++ это не примитивная скриптуха типа раста, где это невозможно сделать и приходится таскать оригинальные объекты.
Поэтому мы можем использовать raii-объекты как стореджи, а далее использовать view-объекты для доступа. Правда непонятно почему не подходят ссылки — почти везде для данного кейса их можно использовать. Я понимаю раст-скриптуху, где ссылки это муоср неудобный, но в С++ с этим проблем нет. Семантика, конечно же, сложная. Но на то он С++, а не примитивная скриптуха.
Поэтому если не хочется перемещать(читай копировать с вызовом не раишных конструктуоров/деструкторов) raii-объекты и есть гарантия, что изначальный объект не сдохнет быстрее копии. Можно просто сделать ptr_view, в который любой sp может каститься. А он pod — он уже копируется как нужно.
В этой скриптухи вообще никаких понятий нет. Там есть просто беспорядочное копирование чего угодно + все переменные семантически ссылки. move там больше костыль для примитивного статического анализатора.
Почему вам так трудно это понять. В скриптухе просто поды из сишки. Всё. Никаких конструкторов, дестркторов и времени жизни нет. В С++ это есть и уже поверх этого создано raii.
Скриптуха взяла raii из крестов, но оно там совершенно другого вида. Как бы попроще объяснить. В общем, если на примере с си. Это просто указатели, которые можно как угодно копировать. А потом магическим образом где-то компилятор вставить free.
Это примерно как cleanup, только чуть более импрувнутый, что в основном связано с примитивность самого языка и нагрузки на адептов.
Копирование и так поведение по умолчанию. У вас с этим проблемы большие. Есть язык — его логика совершенно иная. Не раишные. Базовая семантика языка другая, а раии это просто некая логика прикрученная сверху.
Ненужно это путать. И ненужно пихать это на уровень языка.
У меня такое ощущение, как я уже говорил, что вы какие-то тайные "засланники". Вы не думая пишите какую-то чушь. Т.е. вы занимаете пропагандой мусорной скриптухи и враньём про то, что пишите.
Допустим, чушь про лямбды. Лямбды в раст-скриптухи — это паста []{} — базового синтаксиса из крестов и руби. Т.е. в скриптуха слишком примитивная — там ненужен список захватов. Точно так же в скриптухи слабая система типов — типов там вообще нет. Поэтому там и ненужны типы.
А вообще подобные примеры — позор:
Я даже не буду говорить о том, что это синтаксический мусор и С++ не тот язык, который помойка. Так же, С++ является языком, а не примитивной скриптухой. Поэтому такой мусор в С++ вообще ненужен.
Нет, очевидно. Там голые структуры из llvm(читай си). Никаких методов и деструкторов нет. К тому же, заметим, что я не говорил ничего про деструкторы, но адепт уже начал про них что-то рассказывать? Почему? Правильно — он не читал, не думал — он просто ретранслирует пропаганаду.
Есть только drop, который не деструктор. Это что-то типа finalize в жава. Раст это изначально скриптуха с ГЦ, к которой просто накрутили костылей.
Никаких методов нет — есть просто отдельные функции. Перегрузки нет, поэтому взятая из C++-перегрузка превращена в трейты, которые по-сути являются костылями/сахором поверх перегрузки.
Никаких прав доступа, наследования и прочего — нет, очевидно. Инициализаторов полей нет, конструкторов нет. Есть просто списки инициализаций из си.
Роднит их то, что это это и есть структуры си. А тривиально перемещаются они так же, как подобные структуры в C/С++.
Это уже костыль. В связи с тем, что объекты в расте беспорядочно копируются, потому как по природе это скриптуха с ГЦ. Все типы ссылочные, переменные не являются стореджем как в С/С++.
Далее это вызвало проблему, когда для реализация asyn ансейф-хак падал, потому как нужно было брать ссылки, которые умирали.
Опять же, не только.
Это не права доступа. Это костыли из модулей, о которых я ничего не говорил. Я говорил про права доступа для полей.
Опять же, чушь. Ничего они не решают. Ненужно в ответ мне ретранслировать пропаганду локальную — она мне не интересна.
Трейты — это нахлабучка поверх перегрузки. Она никак не влияет на структуру.
Опять пошла пропаганда второсортная. Ещё раз, меня не волнуют сектантские лозунги и за аргументацию они не считаются.
Дополнительные возможности — это следствие. Основное свойство конструктора — это создать класс функций, которые именно создают объекты. А дополнительные возможности — это вторично.
Нет, очевидно. Опять мы видим сектантские лозунги. Никакого гибче нет — это просто отдельные функции инициализации из си. То, что было тысячи лет до того, как появились конструкторы.
Единственная разница, что в этой скриптухе эта функция не просто валяется в глобальном скоупе, а диспатчится по имени. Это типичная инициализация через статические методы, привет жава, привет 95.
Но в основном они нужны потому, что в данной скриптухи нет перегрузки. В жаве так же, поэтому там так же используются статический методы для не-стандартных инициализаций. Очевидно, что это мусор. Непонятно кто, что и куда инициализирует.
В тех же условных наследниках жавы с нормальным дизайном, допустим dart, эта проблема решается именованными конструкторами.
Пошло полное повторение тезисов из методички, которая оправдывает дыры в дизайне этой скриптухи. Насколько же это нелепо.
Всё это ничего не значит. Тут адепты немного перепутали реальность. Пропаганда им внушает, что их реалии — это что-то новое, но нет. Это 70 год. Самый примитив. Поэтому, если каким-то чудом я стану адептом этих лозунгов — я всегда могу использовать статические методы.
Мусорные лозунги. Это было в 70 году в си. Это ничего не значит. Смысл инициализации именно в том, что конструктор и есть атомарный инициализатор.
Всё это нужно в скриптухи, в нормальном языке есть исключения. Я уже давно жду, что-бы какой-то адепт мне это сказал. Посмотрим, получится в этом раз.
К тому же, от создания объекта — мне нужен объект, а не мусор. К тому же, зачем мне перечислять примитивную чушь? Я понимаю, что пропаганда убедила адептов, что это какие-то новшества, но нет. Это то, что существовало ещё до рождения данного адепта.
Основания. Хотя глупо это спрашивать — Trivially relocatable — это базовое свойство всего в си. Когда там это было никакого раста в принципе не существовало, но в любом случае я жду оснований. Да и никаких понятий "relocatable" в расте в принципе нет — там голые структуры взятые из llvm(читай си).
Т.е. нет никакие конструкторов, нету наследования, прав доступа, инициализаторов и прочего.
Зачем этот мусор в языке?
Ну дак и в вашем решении всё тоже самое. У вам такие же енумы.
Не в этом дело. Дело в пересечении. У вас один енум на двух регистрах. Зачем одно и тоже значение писать сразу в два регистра? Это какая-то общая конфигурация? Как оно должно работать.
Тоже самое непонятно каким образом смешивать разные енумы? Зачем в разных енумах то, что потом смешивается? За счёт чего достигается безопасность?
Насколько я могу могу понять — разделение на разные енумы — это типа костыль для "понятных названий"? Опять же, зачем здесь енумы?
Это всё крайне сомнительно. Вы как-то изначально всё неправильно делаете. Зачем использовать данные в качестве флага?
Интерфейс — это интерфейс. В нём не должны торчать какие-то данные, кишки, енумы и прочее. Особенно если вы хотите constexpr. И какой-то реальной безопасности.
В общем я так и не понял что вам нужно. Дайте ссылку ну C++-api — хоть посмотрю.
Вот ваша задача.
Во-первых здесь ошибка. Если CR и все флаги —
enum class cr, то никакой проблемы нет. Проблема здесь только для обычного енума. Таком образом на С++ левый вариант так же проверяется.Всё, и никаких проблем. Причём ide при написании | сама подсказывает нужные флаги.
Далее вы так и не ответили на вопрос — зачем записывать сразу в несколько регистров. Я вижу тут только дыру в реализации. Я не особо разбираюсь в мк"ашках и видел их последний раз много лет назад. Да и потолком моего знакомства было ваяние генератора сигналов.
Теперь вернёмся к примеру на С++. Вы утверждали, что там всё проверяется. Но когда я вам показал точно такой же интерфейс, только с РЕАЛЬНЫМ компилтайм-вычислением флагом — вы мне сказали "там ничего не проверяется". Вы это так же не прокомментировали.
Непонятно, что вам там непонятно. Флаги заменяются на вызов методов. Сам флаг передаётся через тип. Ничего невозможно никуда передать, точно так же как это сделано в примере выше — у вас попросту нет будет нужных методов.
Если не стоит задача сделать реальный constexpr — достаточно просто смены интерфейса. Нам нужно вначале составлять значение, а потом уже писать. Делается точно так же как в с маской — я показал.
Если хочется и аргументы передавать как constexpr, то это так же без проблем делается. Вариантов много. Передавать через nttp.
Так:
Можно использовать уже value-подход.
Можно так, если нужно принимать не только cr.
Первое здесь правильный value-подход. Вытаскивание типа через nttp — это такой больше костыль.
Можно вообще отказаться от enum. И сразу определять флаги в виде привычном для value-подхода.
Повторяю ещё раз. Я не увидел какой-то валидации сверх enum class и его достаточно. Так же здесь нет constexpr, о чём я уже сообщал выше. Проблему показанного С++-интерфейса можно решить просто отделением билдера.
Единственный функционал какой здесь — это диспатч по регистрам в зависимости от типа enum"а. Но я считаю это не фичёй, а багом. Вы не прокомментировали это.
Причём тут список типов?
Я показал как, тот же ranges показал как — там 1в1 первый вариант.
Очевидно, что она есть.
Причём тут тоже самое? Речь ни о реализации, а об интерфейсе для пользователя. Это какие-то непонятные мне манёвры.
Вы не понимаете как это работает. У вас там никакого constexpr-контекста нет. То, что вы натыкали туда constexpr — это ничего не значит. Смысл подхода, который вы повторили именно в том, что-бы иметь контекст вне контекста.
https://godbolt.org/z/dTmqgt — это было предсказуемо. Реально там ничего не constexpr, для чего не определяется constexpr-контекст явно. А он там определяется только в if constexpr и всё, может где-то ещё.
Потому как аргумент лямбды не constexpr, даже если op() выполняется в constexpr-контексте.
С чего вдруг оно неизвестно? Оно не может быть неизвестно. Это, опять же, непонятные мне манёвры и попытка придумать новую задачу, что-бы оправдать неудачный подход.
К тому же, если он неизвестный, что что делает какая-то лапша в Register1, в
static constexpr void set(Ts...args)и остальных местах? Т.е. это уже попытка реализовать ту самую "известно", причём руками. Причём лапшой.Здесь просто реализована функция set, которая непонятно что, как и куда записывает. Это не реализация интерфейса показанного выше. Это просто форчи + фильтр.
Дак у вас нет никакого подхода. Вы не реализовали то, что показывали выше. Вы реализовали именно сишный вариант.
Он тайпчекается, в enum class — не записать не те значения. Этой фишка есть по умолчанию.
У вас осталось только одно — это диспатч по типу значения в регистр. Это просто побочный эффект и я не вижу его выше. Да и не факт, что он вообще адекватен задаче.
У меня нет явной связи с регистрами, таким образом непонятно на каком основании невозможность задать значение общего енума для одного конкретного регистра. Это очень похоже на дыру в реализации.
В общем, вы как-то более подробно опишите то, что вам нужно. Я вижу только аналог си-интерфейса. Я вижу попытку сделать типобезопасный enum, но он уже есть. Я вижу какую-то непопонятную логику с записью в два регистра сразу. Которой управлять нельзя.
Опишите — я напишу реализацию. Пока что я ничего не понимаю.
Как нет, если есть.
Очевидно, что всё нужно переопределять.
Я объяснил почему и что.
Я привожу пример доступный. К тому же здесь нету никакого нового паттерна — это паттерн уже был изначально. Я просто разделил конфигурацию его.
А из жавы там не паттерн, а подход.
Опять же нет. Он такой же, как и базовый. Если набор методов зависит от some_stream — это так же не проблема. Его/его тип можно использовать для создания билдера.
Можно.
Там так же всё написано один раз. В к тому же потерять всё и игнорировать этот факт — это плохой подход.
Именно лучше. У первого варианта нету никаких преимуществ — одни недостатки.
Ну дак в этом проблема. Ведь смысл то не в списке типов, а в разделение состояния на constexpr в шаблонах(в типе) и на рантайм(в данных).
А задача безопасности — быть незаметной. Страдать за веру — это не подход С++.
Ах да, код не работает в шланге из-за "как попало без захвата". [=]
Для меня это не очевидно, да и это не С++-подход. Это скорее си с классами подход.
Это проблема си с классами/жава подхода. Да даже проблема не их, а просто неправильного api.
А здесь всё теряется. Удобство использования. ide асист не даёт, отдельно сеттеры не валидируются и прочее. Ошибку плюёт сразу в вариадик-лапшу, а не в отдельные функции. Никакие флагсеты не запишешь. Нужно костылить дополнительно то, что ниже.
Поэтому правильными подходами будет два подхода.
https://godbolt.org/z/hs9BwL — второй пример элементарно делается. Правда там должны быть типы, а не рантайм-фигня.
Второй лучше тем, что лучше асист. Если там много всяких флагов — с первым запутаешься. Но первый лучше тем, что как и обычный | записывать наборы флагов в переменные.
Хотя и билдер это позволяет сделать, но менее универсально. Хотя можно реализовать какой-то метод .extend(other)/+/| вставлять даже в середину/конец, а не только начало.
Правило простое. Все изменения производит на уровне типов, тогда получаем constexpr-контекст везде. Рантайм-параметры таскаем как значения.
Про:
Уже сказали.
Наследовать так же лучше как-то так:
: enum_list<Enum1, Enum3>Тогда все эти магические типы пропадут.Методичка потекла. Я не обязан доказывать отсутствие чего-то — это задача адепта доказывать присутствие. В данном случае важности.
Ещё раз ссылку, к тому же там говорилось не только о ссылке.
С чего вдруг? Я лишь доказал в том, что мой оппонент ваяет примитивное легаси-говно, при этом заявляя себя как эксперта и заявляя то, что хаскель может заменить С++. При этом, почему-то легаси-дерьмо ваяет на плюсах.
Тут явные проблемы с логикой и методичкой.
УБ нет. Аналогично: если вам не нравятся доказательства, то вопрос не к доказательствам, а к вам.
Задача адепта предоставлять доказательства заинтересованности.
Т.е. ничем?
Нет.
Нет, адепт не дал никакой ссылки. Адепт просто болтает. Всё, что болтает и на что нет пруфов и обоснований(хоть каких-то) — балабольство. Никто не просит болтуна идти и в стандарт — он всё ровно ничего не знает и не осилит его прочитать.
Нужно хотя-бы показать основания. Почему это так, а не иначе. Привести хоть какие-то доводы, а не бла-бла я так сказал.
Такие, почему адепт ваяет примитивное легаси-говно на С++, а не бороздит космос на хаскеле.
Имеет. Основания. Я их предоставил. Болтун нет.
Во-первых адепт не доказал наличия там УБ и его нет. Во-вторых УБ ничего не значит и никого не интересует и никак болтуна от ответа не освобождает.
К тому же, болтун даже тут сел в лужу. Нельзя УБ как-то трактовать. Опять болтун где-то услышал какую-то чушь и повторяет.
Чем же?
Нет. Опять позор нелепый.
Если это неважно, зачем адепт об этом пытается сообщить?
Мне ненужно ничего гуглить. Я сказал — адепт поломался. Задача адепта скриптухи доказывать то, что в ней что-то есть. Я не занимаюсь поиском херни.
Задача показана — задача адепта воспроизвести, а не болтать.
Опять какая-то чушь. Опять адепт пытается нести херню вида "почему самолёты летают так медленно — я вот вчера своё корыто затюнил в 2 раза". Потому что, адепт, это разные миры. То, что происходит в твоём колхозе — ничего не значит. Они не соответствует тем требованиям, что предъявляются тут. А то, что запросы у тебя нулевые — это лишь следствие твоих примитивных запросов.
Какой код? Отвечать нужно за болтовню. Я дал задачу на демонстрацию диспатча и инлайна. Ваша задача воспроизвести. Не сможете — ты сели в лужу.
Я сразу сказал, что адепт начнёт эту историю про скриптуху. Никакой хмл, хтмл и прочие скриптушное нечто — ненужно.
С++ куда мощнее и выразительнее для описания любых данных, текстовый мусор — удел скриптухи.
Единственное, почему С++ используется там, где есть этот мусор — это то, что скриптуха не может работать быстро и надёжно. Поэтому приходится приходить королю и разруливать.
А так, это задачи недостойные С++. А даже если кому-то это понадобиться — это реализуется за пол дня, как я уже говорил. Правда никому это ненужно, хотя может кому-то и нужно и там это уже есть.
Нет, кстати, здесь можно заметить типичную неадекватную логику.
Подождите, но ведь оно тоже не стандартное. И что, поломалось методичка?
К тому же, это полная чушь. Ничего этого в этой скриптухи нет. Адепт врёт. А колхоз-интроспекция уровня начальной школы, либо eval — этому уже лет 30 в скриптухи.
Опять адепт пытается кичиться общими(бесплатными) свойствами скриптухи выдавая их за свойства отдельной скриптухи.
Во-первых адепт не может мне рассказывать про смогёт, пока не ответит за прошлой смогёт.
Во-вторых — файлы это уровень скриптухи. В не скриптухи существует только код. Всё код. С файлами в пхп.
Это, кстати, типичный подход адептов скриптухи. Прибегают с какой-то ахинеей и начинают её требования. Сама ахинея ничего не стоит. Чтение файла в блоб реализуется за максимум те же пол дня. Почему никто не реализовал? Да потому что это нахрен никому здесь ненужно.
Кстати, это же методичка про интернет. Я потом линкану предыдущие рассуждения данного адепта. Там тезисы того же уровня, а может даже выше.
Отвечу сразу на тему плагина
В общем, поверх языка всегда надстраивались всякие левые правила для внешних инструментов, в том числе компиляторов.
Вначале это были просто всякие хинты в комментах. Но хинты на то и хинты, что они чисто декларативны. Это мета-аннотации.
Всякие макро-расширения уже позволяли производить логику. Ну вот в раст перепастили такой отдельный, левый макро-язык. Это вообще не раст.
Для языка это что-то типа комментов. Типичный макропроцессор из си. Правда в си он был изначально отдельной программой, но сейчас он по-сути часть компилятора.
И этот отдельный язык может инлайнится в файлы с раст-кодом. Это допустим как инлайнинг тестов.
Т.е. это код, код на внешнем языка, который исполняет компилятор. Это расширение логики компилятора. И семантически и с ТЗ реализации.
В расте объектная модель примитивная как топор. Там есть только структуры как в си(из llvm). Больше ничего нет. Нет методов, нет областей видимости, наследования и всего того, что и делает интроспекцию сложной.
https://godbolt.org/z/BMGSSU — это, конечно, вещь несоизмеримо более мощная. Но пример и подход тот же. Плагины писать сложно — поэтому реализуется dsl для удобной го написания правил. Но по-сути это расширение.
Я не удивлюсь тому, что кто-то уже реализовал инлайнинг этих правил в С++-атрибуты/комменты.
Так же, это на тему того о чём я говорил. Что делает это за пол дня. Из этого выхлопа можно сразу генерировать адептеры, а далее язык всё может сделать сам.
Да и, как я уже говорил, существует реализация рефлексии/интроспекции для С++. Реализовать там поиск поиск поля с нужным типом достаточно просто: https://godbolt.org/z/nGjMro
И это не плагин, это не макросня и не внешний язык. Это именно С++ код. Это такая же функция, которая вызывает обычные функции, получает обычные результаты. И может на порядки больше, чем убогая скриптуха/макросня из скриптухи.
Любой адепт уверяет всех, что он не адепт. Это стоит ноль.
Оно имеет вполне очевидный смысл. Просто адепты пытаются казаться какими-то уникальными и независимыми. На самом деле у них одна методичка на всех, они все из одной секты. Там достаточно пойти полистать комменты.
Ещё раз, явление в какой-то среде называет так только в рамках среды. Вы опять палитесь. То, что вы думаете, что ваша среда(читай учение о поклонение очередной скриптухи) может диктовать условия всем — это типичный сектантский паттер поведения.
Поэтому, я могу это называть как хочу. У меня есть тому основания, которые вы проигнорировали. У вас же никаких оснований нет, кроме ссылок на методичку какой-го учения.
Опять адепт пытается рассказывать о том, что несоблюдения догматов какой-то секты автоматически определяет твои суждения не верными.
Не нужно.
Есть вероятность того, что собеседник севши в лужу начнёт придумывать своим словам новые смыслы.
Для этого ненужно паранормальных способностей.
Очередной адепт скриптухи начал отождествлять себя с какой-то официальной принятой терминологией.
Хотя на самом деле он ссылается на догматы локальные своей веры, т.е. конкретной скриптухи. В данном случае раста.
Во-первых, скриптуха сама определяет что и как называть. Никакой "официально принятой терминологии нет". Во-вторых — меня не должно волновать то как адепты очередной скриптухи что-то называют. Это должно волновать только других адептов.
Это настолько удивительно, что каждый адепт очередной скриптухи пытается убедить кого-то в том, что этот кто-то должен принять его веру?
Читать нужно — "я сел в лужу и попытался нелепо оправдаться", типа "я сразу не понял, что ты дурак, но ты дурак".
Ну да, ссылка не соответствует описанию.
Ну да, в отдельной ссылке без какого-либо упоминания её в нужном контексте.
Если бы он их не убирал — там было бы минимум более 200 строк на каждый енум.
Это не публичный интерфейс.
Там нету отсылки на то, что решение не полноценно. О чём я и сообщил. Т.е. оборачивать надо и ваши енумы туда попросту не засунуть. К тому же, я нигде не говорил, что что-то чему-то там противоречит. Я лишь сообщил, что упомянутое решение не соответствует описанию. Всё.
Не вижу проблемы ни в первом ни во втором случае. В любом случае это просто детали реализации — https://godbolt.org/z/RzFTL5 — вот, никаких строк нет.
Плагин это не только:
Это что угодно, что предоставлять/использует внутренней/внутреннюю логике/логику компилятора.
Это другой, левый язык. Когда используется макросы — язык сам себя определяет несостоятельным.