LINUX.ORG.RU

Rust: преобразования указателя на трейт в конкретный тип

 


1

7

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

use std::collections::HashMap;
use std::any::TypeId;
use std::rc::Rc;

trait MyTrait {
    fn new() -> Self where Self: Sized;

    // Тут ещё какие-нибудь методы
}

struct MyStruct {
    items: HashMap<(i32, TypeId), Rc<dyn MyTrait>>
}

impl MyStruct {
    fn get<T: MyTrait + 'static>(&mut self, key: i32) -> Rc<T> {
        if let Some(item) = self.items.get(&(key, TypeId::of::<T>())) {
            item.clone() as Rc<T>
        } else {
            let item = Rc::new(T::new());
            self.items.insert((key, TypeId::of::<T>()), item.clone());
            item
        }
    }
}

Как правильно конвертировать элемент при его извлечении в тип T?

★★★★★

Последнее исправление: KivApple (всего исправлений: 2)
Ответ на: комментарий от Virtuos86

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

Именно что с «царьком». На пресловутого «Царя» не тянет - ни по IQ, никак. Да и лексикончик у персонажа - как у “Эллочки-Людоедочки»…

bugfixer ★★★★★
()
Ответ на: комментарий от technic93

Да, верно, и что? В switch/case тоже можно сделать блок с if-ом. Условно:

match Some(12) {
    Some(x) if x < 0 => { /* 1 */ },
    None => { /* 2 * / },
    Some(x) if x == 0 => { /* 3 */ },
    _ => { /* 4 */ }
}

Это то же самое что

match Some(12) {
    Some(x) => if x < 0 {
        /* 1 */
    } else if x == 0 {
        /* 3 */
    } else {
        /* 4 */
    },
    None => { /* 2 */ }
}

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

anonymous-angler ★☆
()
Ответ на: комментарий от bugfixer

На пресловутого «Царя» не тянет - ни по IQ, никак.

Не знаю на счет «пресловутого», но этот явно тот самый кадр, с которым мне не повезло начать общаться году эдак в 2017-ом, если не раньше. Только тогда он откровенно бредить в своих простынях начинал раньше. Сейчас либо же медикаментозное лечение сказывается, либо я уже просто не вчитываюсь больше, но кажется, что откровенно бессвязного бреда, когда следующая фраза противоречит предыдущей, стало поменьше.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Не знаю на счет «пресловутого»

Этот - явно мимикрирующий школьник. Беспросветный. Забить, и в игнор (как я и сделал).

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

bugfixer ★★★★★
()
Ответ на: комментарий от right_security

Я тебе даже больше скажу - нельзя написать первый компилятор си на си. Как и любого другого языка.

По-моему, это общеизвестный факт, что первый компилятор паскаля был написан на паскале. И оттранслирован вручную.

unC0Rr ★★★★★
()
Ответ на: комментарий от bugfixer

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

Ахаха, посмотрел его доносы. Да, не те нынче сумасшедшие сишники пошли, какое же позорище 😂

Virtuos86 ★★★★★
()
Ответ на: комментарий от khrundel

Не «принимается», а «признаю, что сишный визит - говно и никакого контроля за полнотой там нет».

Компилятор обеспечил покрытие обработчиком всех альтернатив, выполнив проверку в компайлтайме. Если ты не знаешь, что обработчик int пригоден для обработки char – ты не знаешь крестов. Что, впрочем, уже многократно было показано тобой же ранее.

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

Какая фича здесь не работает, шиз?

Коль скоро этот тупой std::variant обещает индексировать варианты по их типам, то путать их он не должен

Бездарность, visit ничего не «перепутал». Перепутал типы ты.

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

Никого не волнуют идиоты. Если ты идиот – у тебя и так ничего работать не будет, сколько тебя не охраняй.

Нет, это ты идиот. Тупой как пробка.

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

в которых я рассказываю о реализации типа-суммы в С++ на примере Boost.Variant.

Дебилоид. Я писал о плюсах до std::variant.

Бездарный идиот, какое нахрен отношение имеет std::variant к Boost.Variant?

если нужна тебе тип-сумма, то на старых плюсах ты делал её наследованием.

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

Родство с плюсами из 90х признавать не хочешь

Цитату, ссылку на сообщение.

, но и сказать, что за принципиальное изменение создало современные плюсы, которое при этом не существовало в 90х, ты тоже не знаешь.

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

Ты заврался. Речь шла о периоде, и только когда ты понял, что ты слит, ты решил потребовать магическую фичу. Но я отвечу: constexpr, auto, вариадики и замыкания.

Сейчас он попытается съехать на «не увидел», «не заметил», как он уже многократно делал ранее в ходе обсуждения.

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

Он должен инкапсулировать, а не иметь доступ к кишкам отрисовываемых классов.

Где тут хоть одно слово про «полиморфизм»? Нет его. Сказанное вполне понятно, енумы неудобны, не расширяются, поэтому, все пользуются трейтами.

Балабол продолжает вырывать цитаты из контекста, в котором я доказывал, что visit отличается от match расширяемостью, которая достигается через полиморфность.

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

Балабол пытается сделать вид, что он не увидел, что в одной из лучших программ на Rust, ripgrep, enum’ы используются в 6 раз реже, чем структуры – статистика, которую я приводил ранее, и что «публичный интерфейс» я использовал как пример легкой метрики.

Причем пример с ripgrep показателен еще и тем, что это не библиотека, которой важно быть расширяемой и поддерживать стабильный интерфейс (в Rust звучит как шутка), а утилита.

Матч по результату, матч по перечислению ошибок - это типа норм, так можно.

Нет, это полное дерьмо, которое в Rust только потому, что это бездарный язык, в котором иначе нельзя.

А вот матч по полезным данным - это не, так нельзя, надо трейт пилить.

Речь вообще не о полезности данных, а о полиморфности. resolve ты для Ok и Err не напишешь, потому что резолвить ошибку это бред.

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

Полное дерьмо. В реальном языке реализуется SBO, опционально с параметром для размера вектора. В Rust – это убожество.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от anonymous-angler

А то что jump таблица по тегу имеет мало отношения к матчу. Поэтому матч это семантически сахар для if/else if цепочки. Потому что там можно и строки матчить и числа и просто if вставить напрямую.

technic93
()
Ответ на: комментарий от khrundel

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

Дятел ты про паттерн визитора слышал? И еще объясняй быстро что это за говно и где матчи с енумами https://docs.rs/serde/latest/serde/de/trait.Visitor.html ?!

technic93
()
Ответ на: комментарий от Siborgium

Компилятор обеспечил покрытие обработчиком всех альтернатив, выполнив проверку в компайлтайме

Я привёл тебе пример некорректной программы, которую твой визит/оверлоадед пережевал. Ты можешь и дальше усираться на тему «а так и должно быть», но ты слит. Вопреки твоему балабольству, проверка на полноту не работает. Даже когда случайно компилятор начинает жаловаться, это не потому, что реализация реально может проверить полноту, нет, просто компилятор не знает как обработать один из вариантов.

Трагично в этой истории то, что ты претендуешь на экспертность в области плюсов, а в реале разбираешься в тонкостях хуже чувака, который живые плюсы в 2005 году в последний раз видел. Заметь: специалистов по плюсам в мире ещё очень много, наверняка и тут полно. Но защищать идею «в плюсах сделано по-человечески» решились только 2: поехавший фанатик Царь, и ты, не разбирающийся в плюсах дальше копипаста пары трюков со стековерфлоу. Те кто чуток здравомыслящий и при этом знает как эти самые плюсы работают, никогда бы не стал всерьёз говорить, что std::visit(overloaded{…}) является хоть сколько-то вменяемой заменой матчу.

Какая фича здесь не работает, шиз?

Заявленная тобой проверка полноты визитом.

Бездарность, visit ничего не «перепутал». Перепутал типы ты.

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

Никого не волнуют идиоты. Если ты идиот – у тебя и так ничего работать не будет, сколько тебя не охраняй.

Пока что «идиот» водит тебя носом по столу.

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

Ну это неправда. Контекст в структуру запаковал я, тот самый dbaccessor. А ты долго прятал реализацию в волшебные функции с 1 параметром и только когда я тебе предъявил код, который сломается, ты вспомнил как тебя когда-то учили и запилил перегруженный метод получения контекста. И сейчас мне доказываешь, что ты бы 10 лет назад так и сделал, честно-честно. При том что несколько дней назад в предложенным тобой же коде никакого контекста не было, при том что условия задачи не изменились, и там и там было получение объекта из БД по одной из возможных схем идентификации.

Чучело пытается съехать с того, что википедия не считает наследование реализацией типа-суммы,

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

Сейчас он попытается съехать на «не увидел», «не заметил», как он уже многократно делал ранее в ходе обсуждения.

Естественно не заметил, или ты думаешь, что я поразился твоей мудрости, побоялся отвечать, но потом зачем-то снова стал требовать ответ? У тебя шиза.

Но я отвечу: constexpr, auto, вариадики и замыкания.

Тут в общем-то и всё, мои полномочия заканчиваются. Ты походу тупо собрал все нововведения, о которых смог вспомнить. Удивительно что добавление constexpr, штуки в общем-то бесполезной если не зацикливаться на мелкой оптимизации, ты упомянул, а r-value референсы, экономящие гораздо больше, забыл. Я только тебе напомню то, что появилось раньше

  • инкапсуляция
  • полиморфизм (в т.ч и динамический)
  • наследование
  • шаблоны
  • эксепшены
  • RAII
  • STL
  • const
  • type&
  • операторы
  • rtti

Всё это было хренью и, как ты говоришь, сахарком над старым добрым C. И только auto, constexpr, вариадики и замыкания сделали C++ отдельным языком.

Цитату, ссылку на сообщение.

Клоун, ты же тут писал про «C с классами», которые не в счёт. Ты совсем заврался. Смотри, всё что нужно было - это признать что да, в плюсах совершенно не хватало типа-суммы. Что задачи, решаемые таким вот енумом как в расте, решались через жопу. Но ты начал врать, что вариант был всегда, хоть в бусте, хоть в каких-то наколенных поделках, хоть без твоего оверлоадеда, который тоже какого-то недавнего стандарта требует, это тоже выглядело совсем всрато. Но ты начал спорить, начал нести ахинею про C с классами и вот сейчас загнал себя в угол.

Он должен инкапсулировать, а не иметь доступ к кишкам отрисовываемых классов.

Ты явно дальше книги «C++ за 21 день» не продвинулся.

Какие кишки могут быть у отрезка? 2 точки? Почему вдруг они стали «кишками»? Ты реально будешь сейчас мне рассказывать, что

class Line {
  ...
  const Point& p1() const;
  const Point& p2() const;
}

это инкапсулированная классная штука, а растовский

enum Shape {
  ...
  Line(Point, Point) 
  ...
}

это «кишки наружу»? Да ты наркоман.

Балабол продолжает вырывать цитаты из контекста, в котором я доказывал, что visit отличается от match расширяемостью, которая достигается через полиморфность.

Я знаю, что ты там пытался доказывать, но факт остаётся фактом, ты свистел, что в расте енумы практически не используются. Я несколько раз переспросил, давая тебе шанс дать заднюю, либо пояснить, если ты не так выразился. Ты родил оговорку о енумах в виде флагов, т.е. так, как они используются в C++. По-моему, ты высказался довольно ясно. Более того, когда я написал об обработке ошибок, ты продолжал настаивать, ты заявил, что никто не пилит ошибки через enum, все возвращают трейт. И только когда я указал тебе вот прямо на то, чем является в расте Result, ты переобулся, и начал рассказывать, что тебя не так поняли.

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

Балабол пытается сделать вид, что он не увидел, что в одной из лучших программ на Rust, ripgrep, enum’ы используются в 6 раз реже, чем структуры

И что? Тебя удивляет ситуация, что структуры с фиксированным содержимым встречаются чаще чем тип, содержащий разное? Не хочется срать на твой триумф, но, блин, ты, уж не знаю насколько непредвзято, искал доказательство бесполезности енумов, и в выбранном тобой же проекте, если я тебя правильно понял, одних только объявленных автором енумов оказалось несколько штук. А если прибавить туда используемые библиотечные, типа Result, Option или Cow, то поди ещё больше будет.

Полное дерьмо. В реальном языке реализуется SBO, опционально с параметром для размера вектора. В Rust – это убожество.

SBO = непроходимость тонкой кишки. Ты, видимо, волшебные слова перепутал.

Насчёт твоего высера, скажу просто: завидуй молча. В плюсах, теоретически, конечно тоже можно было бы запихать в variant null, double, vector, только это настолько всрато будет, что никто не будет заморачиваться. Поэтому Small что-то optimization приходится ручками колхозить в конкретных типах. А в расте вот можно прямо руками раз и готово, примерно как ты свой overloaded из проекта в проект копипастишь.

khrundel ★★★★
()
Ответ на: комментарий от technic93

Дятел ты про паттерн визитора слышал? И еще объясняй быстро что это за говно и где матчи с енумами https://docs.rs/serde/latest/serde/de/trait.Visitor.html ?!

О,третий дебил нарисовался.

Это говно, как ты правильно выразился, паттерн визитор. Специально для нашего друга Siborgium замечу, что реализован он без полиморфизма.

Остаётся только догадаться, что ты сказать-то хотел? Что в Расте можно визитор реализовать? Я думаю, это все знали.

Что в некоторых случаях визитор используется? Да, явно используется.

Что в некоторых случаях визитор лучше чем enum? Ну.. вообще не всегда, часто копируют решения из плюсов потому что так привычнее, но в данном случае да, вместо того чтоб вызывать serialize(Field::I32(val)) явно проще написать visitor.visit_i32(val). И не только проще, внутри serialize сэкономится работа на матче.

В остальном вынужден тебя огорчить: ты обосрался.

Во-первых, потому что речь вообще шла о ситуации, в которой объекты разных типов находятся вперемешку в рантайме и их надо обработать. Что лучше, общий интерфейс и trait object или enum. А ты мне что приволок? Где здесь переменная, способная иметь разные типы? Нет, ты приволок заготовку для сериализации/десериализации, которая позволяет макросу заниматься кодогенераций компайлтайме.

Во-вторых, да, теоретически визитор можно использовать для рисования шейпов в разные библиотеки. Но это не решение задачи, это смежная задача.

Можно написать:

draw(...) {
  match shape {
    Line(p1,p2) -> canvas.drawLine(p1.x, p1.y, p2.x, p2.y),
    Circle(center, radius) -> canvas.drawEllipse(center.x - radius, center.y - radius, ....)
  }
}

а можно

visit(...) {
  match shape {
    Line(p1,p2) -> visitor.visiLine(p1, p2),
    Circle(center, radius) -> visitor.visitCircle(center, radius)
  }
}

Как видишь, код идентичный, задачу определения «динамического типа» шейпа твой визитор не решил. Её придётся либо решать так же матчем, либо деревом наследования типа, каждый из которых реализует visit. Это, безусловно, решит проблему засирания классов шейпов тонной функций, но это будет то самое решение, которое ты же и отквотил, цитирую: Тебе настучат по башке и заставят переделывать, так что ты запилишь некий общий интерфейс канваса и сделаешь рендеринг в него, а потом для каждой графической либы запилишь обёртку над ней, с реализацией твоего канваса.

Но ты молодец, знаешь что такое визитор.

PS: и да, на всякий случай: если ты хотел помочь нашему другу Siborgium, то нет. Его поинт в пользу трейта шейп и наследников был в том, что это позволяет добавить новый тип шейпа и не придётся трогать другой код. Визитор тут не поможет, как только он добавит новый шейп, придётся добавлять новый visitX и все реализации визитора надо будет дорабатывать, т.е. он получит именно о, чего он хотел избежать, отказываясь от матча.

khrundel ★★★★
()
Последнее исправление: khrundel (всего исправлений: 1)
Ответ на: комментарий от khrundel

serialize(Field::I32(val)) явно проще написать visitor.visit_i32(val).

Теперь давай также но с visit_seq

technic93
()
Ответ на: комментарий от technic93

Какое visitLine, visitcircle? Какой матч? Ты давай узнай что такое перегрузка для начала.

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

Паттерн визитор подразумевает жёсткую завязку интерфейса визитора на возможные типы. В примерах он часто описывается с именами функций вида visit_A(A* ptr); visit_B(B* ptr)

В языках с удобной перегрузкой для удобства шлабонов или копипасты, иногда делают просто визит, или в случае std::visit вообще operator(). Это, у слабых умом вроде тебя, может вызвать впечатление, будто визитор может не знать о типах посещаемых узлов и, соответственно, что этот список типов может расширяться. В некоторых случаях это даже срабатывает, если запилить визит как шаблон, только это автоматически сломает динамический диспетчинг, чем обломает универсальность визитора, а так же создаёт точку будущих проблем.

Там где перегрузки нет, или она неудобная, как в расте, например, визитор реализуют через имена с типом. В приведённом тобой примере из serde как раз так. Этот вариант менее удобен чем просто визит в виду невозможности тупой копипасты

void accept(visitor) override {
  visitor.visit(this)
}

, придётся править на visit_foo(this) руками. То, что интерфейс визитора жёстко завязан на список возможных «посещаемых» - это документированная проблема визитора. Если ты читал эту самую GoF, там это написано.

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

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Я привёл тебе пример некорректной программы, которую твой визит/оверлоадед пережевал.

4.2. Программа является корректной с точки зрения языка С++ и любого человека, знающего его правила.

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

Перл.

всерьёз говорить, что std::visit(overloaded{…}) является хоть сколько-то вменяемой заменой матчу.

Цитату, ссылку на комментарий.

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

Заявленная тобой проверка полноты визитом.

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

Пока что «идиот» водит тебя носом по столу.

Пока что идиот сидит в луже. «Ветка с интом» является валидным обработчиком для чара согласно правилам языка С++, покрытие всех вариантов полное.

Если бы ты не блеял про то, в чем не разбираешься, а молча писал auto&& – таких ошибок бы не произошло.

у это неправда. Контекст в структуру запаковал я, тот самый dbaccessor. А ты долго прятал […]

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

Ты лжешь. Изначально речь шла про print, а не про resolve. Затем ты заблеял про ресолв, требующий каких-то операций с БД – и я показал, как это реализовать в полиморфном виде, не потеряв расширяемости.

Удивительно что добавление constexpr, штуки в общем-то бесполезной если не зацикливаться на мелкой оптимизации

Клиника. constexpr это качественно новый уровень, официально выделивший новый класс функций, полиморфных по времени исполнения.

Кстати, а нахрена тогда на Rust столько лет натягивали const, если это бесполезная мелкая оптимизация? Так и не натянули полноценно, к слову.

Всё это было хренью и, как ты говоришь, сахарком над старым добрым C.

Мразь опять лжет. Цитату, ссылку на сообщение.

И только auto, constexpr, вариадики и замыкания сделали C++ отдельным языком.

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

Клоун, ты же тут писал про «C с классами», которые не в счёт.

Я устал от твоей брехни, я сейчас пойду писать репорты. По этим ссылкам мразь упорно тупит и делает вид, что не знает, что помимо std::variant был Boost.Variant и наколеночные реализации, и пытается съехать на наследование.

Rust: преобразования указателя на трейт в конкретный тип (комментарий) Rust: преобразования указателя на трейт в конкретный тип (комментарий) Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Какие кишки могут быть у отрезка? 2 точки? Почему вдруг они стали «кишками»?

Потому что следующим у отрезка появится цвет, толщина, градиент, текстура и так далее. И твои «две точки» превратятся в пачку параметров.

Ты реально будешь сейчас мне рассказывать, что

Нет, это дерьмо, которое написал ты.

Ты родил оговорку о енумах в виде флагов, т.е. так, как они используются в C++

Идиот думает, что enum в С++, enum в С, enum «вариант» в Rust и enum-перечисление в Rust это одно и то же, ведь там везде написано «enum». Это клиника.

используемые библиотечные, типа Result, Option или Cow,

Балабол делает вид, что не заметил ответ про Result и Option, все так же вырывая из контекста фразы.

никто тебя бы сильно не гнобил за незнание внутренностей раста.

Позорище, ты обосрался, не зная даже механизма «вывода» типов в Rust и механизма работы лямбд в нем же. И это я еще не припоминаю тебе твое понимание перегрузки в крестах.

SBO = непроходимость тонкой кишки. Ты, видимо, волшебные слова перепутал.

Извини, что задел за живое. Обратись к специалистам, они вылечат.

завидуй молча.

Чему завидовать? Влегкую ломающимся инвариантам? Невозможности просто сделать push? Диспатчу на каждый вызов? Необходимостью делать map при пушах?

В плюсах, теоретически, конечно тоже можно было бы запихать в variant null, double, vector,

Такой мусор можешь написать только ты.

Поэтому Small что-то optimization приходится ручками колхозить в конкретных типах

Спешите видеть, адепт rust рассказывает про неполиморфность. Бездарность не в курсе, что соответствующие реализации существуют в любой зрелой библиотеке на крестах: Boost, LLVM, folly, не говоря уже про отдельные либы, и любая из них является шаблонной, причем не по одному лишь T, а еще и по количеству элементов, которые влезут в буфер перед аллокацией, и самому аллокатору.

Siborgium ★★★★★
()
Ответ на: комментарий от khrundel

Ты высрал в предыдущих постах кучу бреда про «настучат по голове» и что в классическом ооп с виртуальными методами задача не решается. А потом наконец прочитал GoF и узнал что тот визитор с точки зрения семантики это один в один твой матч. Только нафига ты в примере с visit притащил матч? По поводу твоего идиотизма с наименованием visitA(A&), в С++ есть кроме динамического и статический полиморфизм, и как раз перегрузка тебе позволяет использовать один и тот же код и в динамике и в статике. Хоть с virtual, хоть std::visit хоть с template.

technic93
()
Ответ на: комментарий от technic93

Да, и что? x2

match может быть цепочкой if-ов, но не обязан. В теме мы обсуждаем матч enum-ов, и при матче enum-ов он цепочкой if-ов не становится, если ты не указал дополнительных условий. И даже если указал, они всё равно будут после jump таблицы. Но к теме это уже отношения не имеет.

https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=aa802de2d7b42b9309046423182bc422

playground::foo:
	pushq	%rbx
	subq	$96, %rsp
	movzwl	(%rdi), %eax
	leaq	.LJTI7_0(%rip), %rcx
	movslq	(%rcx,%rax,4), %rax
	addq	%rcx, %rax
	jmpq	*%rax

.LJTI7_0:
	.long	.LBB7_1-.LJTI7_0
	.long	.LBB7_2-.LJTI7_0
	.long	.LBB7_3-.LJTI7_0
	.long	.LBB7_4-.LJTI7_0
	.long	.LBB7_10-.LJTI7_0
	.long	.LBB7_5-.LJTI7_0
	.long	.LBB7_6-.LJTI7_0
anonymous-angler ★☆
()
Ответ на: комментарий от technic93

И что? x3

Я не понимаю что ты хочешь мне тогда доказать/объяснить. Что match может больше if/switch вместе взятых и способен оптимизироваться под ситуацию? Я это и так знал.

anonymous-angler ★☆
()
Ответ на: комментарий от technic93

В общем я понял, ты сердцем чувствуешь, что я не должен был быть прав, но сформулировать не можешь.

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

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

khrundel ★★★★
()
Ответ на: комментарий от Siborgium

4.2. Программа является корректной с точки зрения языка С++ и любого человека, знающего его правила.

Чучело, ты работодателю так же говоришь, мол раз откомпилялась, значит корректна «с точки зрения языка C++ и любого человека, знающего его правила»?

Цитату, ссылку на комментарий.

У нищих слуг нет.

До идиота все никак не дойдет, что тезис сводится к тому, что match – дерьмо, замещать которое не нужно, а нужно просто не использовать.

твоя любимая конструкция std::visit(overloaded{}) пытается.

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

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

Пока что идиот сидит в луже. «Ветка с интом» является валидным обработчиком для чара согласно правилам языка С++

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

Если бы ты не блеял про то, в чем не разбираешься, а молча писал auto&& – таких ошибок бы не произошло.

Можешь не пояснять, я уже понял, что для тебя главное что компиляется.

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

Зачем ты мне показываешь ссылку на текст, в котором ты изложил историю в выгодном для тебя свете? Мне не нужна твоя болтовня. Нужна была вот эта ссылка: Rust: преобразования указателя на трейт в конкретный тип (комментарий)

В ней ты начал объяснять, как можно взять и получить правильный контекст, через дополнительную перегружаемую функцию ([](auto && id){ resolve(get_ctx(super_ctx, id), id) }). Идём дальше по истории и попадаем в моё сообщение с таким кодом:

[](const Uuid& uuid) { print(print(s_dbAccessor.get(uuid).name)); }, // во, очень удобно
        [](auto && id) {
            // самая старая ветка, написанная ещё когда оптимизированную get(const Uuid&) функцию не написали. Раньше по Uuid искалось здесь, сейчас или вообще не используется и оставлена для универсальности, или используется для поиска по каким-то редкоиспользуемым полям с ключами хз откуда
            print(s_dbAccessor.findWithUniversalSearchStoredProcedure(id.toString())); }

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

      [](const Name& name) { resolve_name(name.name); },
      [](const Uuid& uuid) { resolve_uuid(uuid); },

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

Правда и это враньё: мы же знаем твою любовь к auto&&-ветке. Почему ты думаешь, что твой get_ctx(super_ctx, id)} не был бы точно так же реализован через auto&& и не вернул бы тот же самый dbaccessor?

Клиника. constexpr это качественно новый уровень, официально выделивший новый класс функций

Не ты ли свистел о том что тебе вообще насрать на то как матч реализован и важно что он есть семантически? И вот теперь ты рассказываешь, как важно иметь возможность посчитать функцией в компайлтайме, что без неё и плюсы не плюсы.

Кстати, а нахрена тогда на Rust столько лет натягивали const, если это бесполезная мелкая оптимизация?

А что, бесполезные мелкие оптимизации не нужны что ли? Но не они делают Rust Rust’ом.

Мразь опять лжет. Цитату, ссылку на сообщение.

Сам поищи, про «C с классами», клоун.

Я устал от твоей брехни, я сейчас пойду писать репорты.

Т.е. ты ещё и стукачок? Ну, неудивительно.

По этим ссылкам мразь упорно тупит и делает вид, что не знает, что помимо std::variant был Boost.Variant и наколеночные реализации, и пытается съехать на наследование.

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

Потому что следующим у отрезка появится цвет, толщина, градиент, текстура и так далее. И твои «две точки» превратятся в пачку параметров.

Нет, клоун, отрезок это и есть отрезок. Это 2 точки. В этом суть объектно-ориентированного программирования, а не помойки, которая получается когда говнокодеры типа тебя пытаются заставить это всё скомпиляться.

Идиот думает, что enum в С++, enum в С

Плохи у тебя дела, если ты уже за такую соломинку хватаешься. Но вообще ты прав, я всегда думал, что в C енум бэкпортнули из плюсов. Их почему-то всегда сравнивали с константами сделанными через #define

По существу-то есть что возразить?

Позорище, ты обосрался, не зная даже механизма «вывода» типов в Rust и механизма работы лямбд в нем же.

Вообще-то я тебе демонстрировал, как раст умеет выводить типы. А ты (или не ты а Царь, но вроде ты), никак не мог понять, почему у лямбды может быть только один тип. Ты, тупица, думал, что если у тебя есть лямбда x + 1, и тип x ты не прописал, то это должно позволять передать в неё хоть инт хоть флоат. Ты думал что это проблема в неумении раста вывести тип. Заметь, я даже не спорю с тобой на тему, должен ли раст предлагать вместо лямбды дженерик, главное в той истории то что ты, клоун, даже диагноз правильно поставить не смог.

И это я еще не припоминаю тебе твое понимание перегрузки в крестах.

Просто напоминаю тебе твой обсёр с ветками char и int& в overloaded. Ты, уже зная суть проблемы, с диким пафосом полез учить меня плюсам, после чего был позорно бит. Так что перегрузку в крестах не знаешь ты. При этом, видимо, активно на них кодишь. Сука, это что за говноязык такой, если опытный программист не может разобраться с тем, почему вариант с чаром может обрабатываться интовой.

Чему завидовать? Влегкую ломающимся инвариантам? Невозможности просто сделать push?

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

Спешите видеть, адепт rust рассказывает про неполиморфность.

Ты на своей полиморфности помешался, шизик. Если у тебя в лифте кто-нибудь напишет «в C++ нет полиморфизма», ты, наверное, дом сожжёшь.

Нет, клоун, ты как всегда нихрена не понял. Я не к тому, что ты должен пилить вектор с оптимизацией для интов отдельно. Конкретные типы - это те самые векторы. Я к тому, что ты должен подключать говнобиблиотеку типа буста ради того чтоб получить вектор с такой вот простой функциональностью. Потому что реализовать её просто вот никак нельзя, если у тебя уже есть просто вектор (или множество, или ещё какая хрень), то добавить в него подобную фигню невозможно, нужно брать и переписывать. А в расте - как 2 пальца.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Ещё раз, для тупых: мне плевать и на boost::variant и на наколенные реализации. В языке из коробки его не было до 2017 года.

Просто ради занудства: в языке из коробки до сих пор нет ни сокетов, ни средств для работы с БД, ни GUI, ни криптографии. Тем не менее, пользуются всем этим в C++ уже больше 30 лет.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous-angler

У enum выше есть дискриминант, а значит он работает как switch и там нет вереницы if-ов.

Вот твои слова. Ты имел ввиду таблицу, т.е. одно таблица а второе это cmp+jumpeq и компания. Там выше ещё речь шла про матч. Я сказал что матч это далеко не всегда просто табличный свитч, потому что матчить там можно по строкам и так далее. Во вторых сказал что ифы это иногда джамп таблицы. Т.е. семантика и реализация матча и ифов в зависимости от ситуации совпадает. Тогда в чем отличие кроме синтаксиса?

Единственное чем отличается это проверка на полноту.

Но цепочки ифов в тс тоже проверяют на полноту, причем лучше чем в расте т.к. там в else ветке на уровне типов остается список не заматченных вариантов, которые можно передать в следующую функцию вместо просто непонятного default/_ как в си/расте.

Этим же свойством (сохранение остатка на уровне типов) обладает std::visit+std::variant в С++. Тогда если рассматривать по этому свойству то match оказывается ближе к цепочке ифов где внутри else {} информация нет никакой.

technic93
()
Ответ на: комментарий от khrundel

мол раз откомпилялась, значит корректна «с точки зрения языка C++ и любого человека, знающего его правила»?

Да. Если ты не знаешь правила языка С++, ты некомпетентен.

У нищих слуг нет.

Балабол пойман за руку. В очередной раз.

твоя любимая конструкция std::visit(overloaded{}) пытается.

Опять ложь. Вернемся в самое начало.

А можно добавить еще один обработчик [](auto && x){ print(x); }, и бесплатно получить возможность добавлять новые типы в Identifier, добавляя их печать лишь если она для них не была реализована.

Через какое-то время даже до тебя дойдет, что портянка из обработчиков не скейлится, в отличие от добавления перегрузок/специализаций, но на это время и так сгодится.

С тех пор я многократно повторял это же самое утверждение, но идиот продолжает лгать.

никак не дойдёт, что недостаточно ввернуть слово «полиморфизм», чтоб доказать превосходство чего-то.

Бездарность, я показал, как это работает – и ты слился.

каким был твой код до того как я объяснил проблему:

Шизоид, как я могу написать код, не понимая, о каком резолве ты говоришь? Ты захотел резолв – я показал, как сделать резолв. Ты захотел работать с контекстом в виде db – я показал, как тебе сделать контекст так, чтобы это скейлилось.

До того как я указал тебе на ошибку никакого контекста у тебя не было.

Ты бредишь. Ты придумал db – я пояснил, как можно делать в таком случае. «Ошибкой» это не является ни в коем случае, db ты придумал позже.

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

В языке из коробки его не было до 2017 года.

Мразь намеренно подменяет понятия. Не в языке, а в STL.

Почему ты думаешь, что твой get_ctx(super_ctx, id)} не был

Почему ты думаешь, что твой print!, реализуемый через built-in компилятора, не делает rm -rf /?

бы точно так же реализован через auto&& и не вернул бы тот же самый dbaccessor?

Но я даже отвечу. В примере get_ctx возвращает разные контексты для разных вводов, их типы стыкуются с типами контекстов в соответствующих им функциях resolve. Если вдруг get_ctx будет реализован некорректно и будет возвращать один и тот же тип для всех вводов, сломается вызов resolve.

Не ты ли свистел о том что тебе вообще насрать на то как матч реализован и важно что он есть семантически?

Какое нахрен отношение имеет матч к constexpr?

как важно иметь возможность посчитать функцией в компайлтайме, что без неё и плюсы не плюсы.

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

Сам поищи, про «C с классами», клоун.

Мразь поймана за руку в очередной раз. Первое упоминание С с классами.

Т.е. странные цепочки is уже не так плохи, когда выяснилось, что они есть в плюсах и их нет в расте?

Я не писал про «плохи» или «хороши». Я написал, что они были во всех языках того времени, и поэтому попали и в тогдашний С++ (точнее, С с классами).

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

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

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

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

Это был даже не С++, а С с классами – а задача уже решалась.

Еще раз отмечу попытки кретина игнорировать Boost.Variant и самописные варианты – хотя его многократно ловили на этом.

отрезок это и есть отрезок. Это 2 точки. В этом суть объектно-ориентированного программирования

Перл.

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

До появления буста C++ так же существовал. Я не понимаю, чё ты так жопу рвёшь, пытаясь сделать вид, будто время до появления варианта в плюсах как бы не в счёт.

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

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

Я даже поясню, почему это – пример попытки мрази съехать с темы полиморфизма.

enum как перечисление констант никакого отношения к enum как tagged union не имеет. Никто и никогда не делает по нему visit, match по нему ничем не отличается от switch. Никаких претензий к такому enum от меня не было.

Все началось именно с утверждения несостоятельности match для полиморфной обработки tagged union, так как это не скейлится – в отличие от variant+visit.

Хотя С++ позволяет сделать тайплевел enum-перечисление и полиморфно обрабатывать и такую реализацию.

Я показал, что match несостоятелен, потому что не скейлится абсолютно и требует, временами, зашкаливающей репетитивности кода.

Сейчас этот идиот пытается съехать на то, что «ну и там и там enum написано», или использовать Result, который к реализации полиморфизма отношения не имеет. Интересно, что бы он блеял, будь в Rust обработка ошибки из Go, где никакого Result нет, а есть x,err := foo(); if err != nil { return err; } ....

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

Да уж. «Опытный» программист не знает про правила перегрузки, правила преобразований типов, про ADL, про SFINAE, но понять свою бездарность он не в состоянии.

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

Идиот, у тебя сломан инвариант. У тебя на каждое действие мувы. У тебя нет никакой возможности кастомизации. У тебя диспатч на каждую операцию с этим убожеством. Где тут «круто»?

то добавить в него подобную фигню невозможно, нужно брать и переписывать. А в расте - как 2 пальца.

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

Более того, ты опять сел в лужу. В Rust невозможно эффективно реализовать SBO для вектора.

https://news.ycombinator.com/item?id=15967586

В этом контексте еще смешнее выглядит его ответ про const:

А что, бесполезные мелкие оптимизации не нужны что ли? Но не они делают Rust Rust’ом.

Правильно, Rust делает Rust’ом бездарность, оголтелый фанатизм и толпы хомячков – и проплаченных пропагандистов.

Siborgium ★★★★★
()
Ответ на: комментарий от eao197

Просто ради занудства: в языке из коробки до сих пор нет ни сокетов, ни средств для работы с БД, ни GUI, ни криптографии.

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

khrundel ★★★★
()
Ответ на: комментарий от technic93

Давай visit_seq пиши на матчах не шлангуй ;)

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

khrundel ★★★★
()
Ответ на: комментарий от Siborgium

мол раз откомпилялась, значит корректна «с точки зрения языка C++ и любого человека, знающего его правила»?

Да. Если ты не знаешь правила языка С++, ты некомпетентен.

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

Опять ложь. Вернемся в самое начало.

Не нужно, клоун, возвращаться в самое начало. Я тебе уже объяснил, почему твоя дефолтная ветка - говно и её быть не должно. Начинать по второму кругу нет никакого желания. То, что ты нашёл чем отличается std::visit с оверлоадедом от матча не значит, что вот эта корявка делает что-то хорошее, фанатик ты тупорылый.

Шизоид, как я могу написать код, не понимая, о каком резолве ты говоришь? Ты захотел резолв – я показал, как сделать резолв.

Довольно убогая отмазка. Мы довольно долго обсуждали идентификаторы. Я на словах тебе описал суть проблемы очень давно. Ты упорно пытался представить, что у тебя есть какой-то волшебный ресолв, который сам всё сделает. И только после того как я написал код, который в подобном проекте будет реально, ты придумал, что у тебя будет особый метод получения контекста. Я объяснил тебе, что если до этого проект работал только с БД и годами никто не планировал другие источники данных, то функции для получения контекста там не будет. Ты это проигнорировал, заявил что все идиоты, кто контекст не предусмотрел изначально.

Почему ты думаешь, что твой print!, реализуемый через built-in компилятора, не делает rm -rf /?

Потому что его писали умные люди, а не ты, например?

Не, давай вот рассуждать разумно. У нас есть говнокодер, вроде тебя, который функции ресолва идентификаторов пишет с авто-веткой. Почему он это делает? Очевидно, потому что считает, что есть какой-то универсальный способ разресолвить любой неизвестный ему вид идентификации. Я это в примере даже отразил, в виде вызова хранимки, ищущей по всем полям. Предположим, ты зачем-то всё-таки решил пилить контексты. Но этот вариант сломает твой универсальный код. Следовательно, нужен универсальный способ получения контекста. Вот и напишешь ты шаблонное получение этого же самого dbaccessor’а.

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

  • В ТЗ речь шла о БД только, так что неудивительно что дефолтная шаблонная реализация get_ctx возвращает бдшный контекст для любого типа. Пусть скажет спасибо что ты ему вообще get_ctx предоставил для последующего расширения
  • Это он идиот, так как ежу понятно, что нужно было добавить специализированный get_ctx для данных не из БД. Ты же даже комментарий рядом с шаблоном написал.
  • Тебя совершенно не волнует, что get_ctx используется только в легаси коде и у них давно всё делается через другой, асинхронный метод. Когда ты писал шаблонный get_ctx это был не легаси, а если он работает над проектом и не знает, что помимо асинхронного get_data_context(), который он правильно переопределил, есть ещё старый get_ctx, то это он некомпетентен и вообще мразь и дебил.

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

Ты вообще дурачок что ли? Примитивы в библиотеки не передаются. Ни как enum, ни даже как класс. Просто вызов drawLine с параметрамии. Даже в упоротой по объектам джаве: https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html

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

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

enum как перечисление констант никакого отношения к enum как tagged union не имеет.

Да ты чё, правда что ли? Я напомню тебе контекст: ты свистел, что енум используется в апи крейтов только для передачи флагов. Я написал об этом «как в плюсах» и ты обрадовался что хоть что-то можешь возразить. Так вот, если использовать enum не как tagged union, то он будет как раз годен только для «передачи флагов». Т.е. в том виде, в котором, по-твоему, он только и применим.

Все началось именно с утверждения несостоятельности match для полиморфной обработки tagged union, так как это не скейлится – в отличие от variant+visit.

Нет, дубина, вариант+визит точно так же не скейлится.

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

требует, временами, зашкаливающей репетитивности кода.

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

Сейчас этот идиот пытается съехать на то, что «ну и там и там enum написано»,

4.2. Заметь разницу между нами: я до последнего даю тебе шанс поправиться и толкую любое сомнение в твою пользу. Ты любое моё умолчание пытаешься изобразить в «хахаха, он не знает X». Причём такую ахинею мне пытаешься приписать.

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

Кстати, а ты помнишь, что Result - это именно tagged union, а не простое перечисление констант? Так что моё утвержение, что tagged union используются везде - оно правдиво. А ты обосрался.

Интересно, что бы он блеял, будь в Rust обработка ошибки из Go, где никакого Result нет, а есть x,err := foo(); if err != nil { return err; } ….

Если бы да кабы. Но я отвечу: замена обработки ошибок на го-подобную сделало бы раст не растом. В отличие от плюсового constexpr, растовые enum’ы - это важная часть языка. Это только на первый взгляд возврат кортежа из кода ошибки и результата похоже на Result. На самом деле растовый синтаксис не позволяет забить на факт ошибки или там перепутать и проверить не ту err. В расте если возвращена ошибка ты тупо не сможешь обратиться к X.

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

Да уж. «Опытный» программист не знает про правила перегрузки, правила преобразований типов,

Так-то речь о тебе. Именно ты жидко обделался, пытаясь объяснить, почему отсутствие char-ветки в примере не вызывает ошибку компиляции.

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

про ADL, про SFINAE

Ещё забавная черта фанатиков плюсов. Вот есть костыль, необходимый для того чтоб шлабоны с утинной типизацией не вызывали ошибку компиляции. Ну костыль и костыль, хрен бы с ним. В плюсах всё же через жопу. Однако в виду того, что из него образуется длинная аббревиатура, то её можно запомнить и вставлять при каждом удобном случае. Ты чем гордишься-то, клоун, что запомнил 6 букв в правильном порядке? Так это просто, проверочные слова «свин» и «нае..»

khrundel ★★★★
()
Ответ на: комментарий от Siborgium

Идиот, у тебя сломан инвариант.

Какой инвариант, дурилка? Инвариант имеет смысл в случае известного интерфейса, а ты его даже не знаешь.

У тебя на каждое действие мувы.

На одно, на добавление 1 элемента к полю, содержащему 1 элемент. Ну и зачем бояться мувов? В расте они сделаны по-человечески.

У тебя нет никакой возможности кастомизации.

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

У тебя диспатч на каждую операцию с этим убожеством.

А вдруг мне пофиг? Не рассматриваешь такой вариант?

Где тут «круто»?

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

Мразь лжет, и даже не пытается выглядеть правдоподобно. Smth это новый тип, ты ничего не добавил в Vec

И что, дебилушко? Мои поля, могу сделать их любого типа. Вопрос в другом: вот есть у тебя под рукой проект с плюсами, на предложение добавить буст тебе отказали, сколько тебе потребуется времени на то чтоб реализовать такую фичу? А в расте взяли и добавили. Потому что tagged union хорошая вещь, и язык, умеющий удобно с ней работать, всегда предпочтительнее чем std::visit(overloaded{}) - говно.

Более того, ты опять сел в лужу. В Rust невозможно эффективно реализовать SBO для вектора.

Дожили, чучело постит сюда ссылки на форумную болтовню. В расте, если что, любое обращение к вектору проверяется на размер. Даже чтение. Так что, «снявши голову по волосам не плачут». Потом, как говорит Царь, «ворованная» LLVM по возможности эти проверки убирает. Тот самый «диспатч», которого ты так боишься - это ещё одна такая проверка, которую точно так же можно дропнуть, если оптимизатор видит что она излишняя.

Я тебе на другой момент укажу. Ты заметил, что все эти реализации векторов с оптимизацией, они отсутствуют в stl? Вот для строк, если не ошибаюсь, есть, а для векторов нет. И все они имеют особые названия, не boost::vector, а boost::small_vector, т.е. непригодны для drop in замены. Причём размер элемента тут не роляет, с помощью шаблонной магии и sizeof вполне можно было бы сделать грубый выбор количества преллоцированных элементов. Что нам это говорит? Что реально с этой оптимизацией всё непросто и требуется осознанное включение этой фичи клиентом. Так что вопрос о возможности эффективной реализации на плюсах так же неочевиден. Возможно реальная причина, почему в расте вектор по дефолту не обладает таким свойством, она вовсе не от того, что там нельзя хранить указатель на себя, а потому же, почему эту оптимизацию не добавляют в STL.

khrundel ★★★★
()
Ответ на: комментарий от khrundel

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

Так же, как и CRC32, Alder32, MD5, SHA1… Ничего из этого не завязано ни на сторонний софт, ни на платформу. В stdlib ничего этого нет. Но в языке используется уже непойми сколько лет.

Вариант это по сути базовый тип, что-то типа массива.

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

Если я понимаю ситуацию правильно, то возможность полноценно и безопасно реализовать variant без костылей появилась лишь в C++11 (variadic templates, alignof/alignas). Тем не менее, разные версии variant в языке использовались со времен C++98, а некоторые и еще раньше, с первой половины 90-х.

Так что включение именно std::variant именно в C++17 – это лишь исторический казус, следствие принципа работы комитета и ограниченности его возможностей.

Более того, мы с std::variant/std::visit имеем еще один казус: для лаконичного использования std::visit нужен трюк с overloaded. Этот трюк стал возможен лишь в C++17 с введением в язык специальных правил вывода типа шаблонов.

Однако, сам overloaded в stdlib почему-то не вошел. Для меня лично это непонятно. И, не исключаю, что данный недочет может быть исправлен в каком-нибудь C++26.

Но, если такое произойдет, то это же не будет означать, что в языке не было overloaded до C++26.

eao197 ★★★★★
()
Ответ на: комментарий от khrundel

Да, ленивая ты жопа. Скопипасти одну строчку.

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

crutch_master ★★★★★
()
Ответ на: комментарий от khrundel

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

Царь всегда был прав. Когда-то и ты это поймешь.

crutch_master ★★★★★
()
Ответ на: комментарий от khrundel

Нет, это до тебя не дошло, тупица. Ты меня бесишь уже, как можно так тупить?
Ещё раз, для дебилов:

Ахаха, несите тазик, у него туз дымится.

crutch_master ★★★★★
()
Ответ на: комментарий от eao197

Так же, как и CRC32, Alder32, MD5, SHA1

Давай оставим в списке только CRC32. Почему я не особо удивлен его отсутствию? Да, это не завязано на платформу. Однако не является и базовым компонентом. Кроме того, почему CRC32? Хэш функций дофига и они не взаимозаменяемы. Для контроля целостности внешних данных нужна CRC32, реализованная 100% корректно, для индексации внутри хэш-таблицы желательно что-то обфусцированное, чтоб нельзя было заддосить передаваемыми снаружи данными.

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

Поэтому я считаю долгое отсутствие варианта в стандартной библиотеке, а так же общую всратость синтаксиса visit-overloaded серьёзным недостатком, а то что это чудо даже полноту нормально не проверяет, ну тут как бы всё. И это происходит на фоне того, как в плюсы на уровне языка добавили for с двоеточием, который может и удобнее, но принципиальных улучшений не приносит. Такое впечатление, что тупо идут на поводу у пользователей, тех задолбало писать for (auto it = cont.begin():...) - им запилили сахарку, а так как вариант используется относительно редко, то и хрен с ним, пусть костылят свой overloaded, исправлять ничего не будем.

khrundel ★★★★
()
Ответ на: комментарий от crutch_master

У тебя уже попка с прошлого раза зажила, за добавкой пришел?

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

khrundel ★★★★
()
Ответ на: комментарий от khrundel

Вариант тут отличается.

Не вижу особой разницы. Кому-то нужен CRC32, а его в stdlib С++ нет, хотя добавить его туда можно было давным-давно.

Кому-то нужен variant, а его в stdlib C++ не было до C++17, хотя добавить можно было и раньше.

Тем не менее, и то, и другое было доступно в C++ давным-давно.

Посему странным выглядит желание утверждать, что в C++ до C++17 variant-а не было вообще.

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

Сильно зависит от стиля программирования. Я, наверное, с 2019-го плотно работаю с C++17, и не могу сказать, что variant так уж сильно используется. Так что здесь и от предметной области многое зависит, и от навыков разработчика, и от «любимой парадигмы».

Поэтому я считаю долгое отсутствие варианта в стандартной библиотеке, а так же общую всратость синтаксиса visit-overloaded серьёзным недостатком

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

Чтобы оценить насколько же всрат visit, нужно дождаться, пока в C++ завезут match (или inspect, если я правильно помню пропозал). Тогда можно будет сравнить частоту и сценарии использования visit vs match/inspect.

Лично мне в C++ не хватает match/inspect, но не в тех сценариях, вокруг которых вы с @Siborgium здесь какашками друг в друга бросаетесь. Как по мне, так главная ценность match/inspect в возможности сделать декомпозицию и провести сопоставление с образцом. Грубо говоря, что-то вроде:

inspect(Point{get_X(), get_Y()}) {
  case {0, y}: ... // На оси Y.
  case {x, 0}: ... // На оси X.
  case {v, v}: ... // На диагонали.
  case {x, y}: ... // Где попало.
}

visit мне так не позволит и в этом для меня как раз и недостаток visit-а. Ну и отсутствие overloaded сразу в stdlib :)

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Однако, сам overloaded в stdlib почему-то не вошел. Для меня лично это непонятно. И, не исключаю, что данный недочет может быть исправлен в каком-нибудь C++26.

Я особо подробностей не знаю, но есть пропозал https://github.com/cplusplus/papers/issues/281 но он пока в обсуждении, я не знаю почему застопорилось…

fsb4000 ★★★★★
()
Ответ на: комментарий от khrundel

Ты реально не понимаешь, что корректность программы определяется не её принятием компилятором

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

Я тебе уже объяснил, почему твоя дефолтная ветка - говно и её быть не должно.

Ты в очередной раз лжешь. От того, что ты напишешь «я тебе уже объяснил» ничего не изменится – ты слился, проблеяв про мифические мины, не приведя ни одной в пример.

Что характерно, именно избегая auto&& ты заложил мину с int и char.

от матча не значит, что вот эта корявка делает что-то хорошее

Ты ушел в тупое отрицание.

Я объяснил тебе, что если до этого проект работал только с БД и годами никто не планировал другие источники данных, то функции для получения контекста там не будет.

Мразь в очередной раз пытается проигнорировать сообщение Rust: преобразования указателя на трейт в конкретный тип (комментарий)

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

Цитату, ссылку на сообщение.

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

Цитату, ссылку на сообщение.

Но этот вариант сломает твой универсальный код. Следовательно, нужен универсальный способ получения контекста. Вот и напишешь ты шаблонное получение этого же самого dbaccessor’а.

Ты совсем поломался. Какой «универсальный» способ? Какое «шаблонное» получение? В Identifier лежит конкретный и конечный набор типов, известный мне в любой момент. Там нахрен не нужен никакой «универсальный» способ получения контекста.

Нет, дубина, вариант+визит точно так же не скейлится.

Опять тупое отрицание.

Кстати, если что, в матче тоже можно запилить дефолтную ветку, и потом так же как ты свистеть

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

А когда к тебе придёт разбираться твой преемник, ты ему ответишь:

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

Примитивы в библиотеки не передаются. Ни как enum, ни даже как класс.

В принципе, на этом можно заканчивать – все ясно.

А знаешь, почему не передаются? Потому что это не скейлится. Добавить метод в класс – бесплатно. Добавить новый элемент перечисления – увеличивает число веток во всех матчах, меняет размер перечисления и количество его элементов, и так далее. Более того, и внутри библиотеки никто не хранит примитивы в виде enum’ов.

пытаешься чуть ли не орфографические ошибки искать.

Смотрим, как он блеял о том, что до std::variant в С++ не было вариантов. Сейчас пытается съехать на «орфографию». Какая же гнилая мразь.

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

на незнании типа char в плюсах?

Не позорься. Символьные литералы к типу char отношения не имеют.

Причём такую ахинею мне пытаешься приписать.

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

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

растовые enum’ы - это важная часть языка. Это только на первый взгляд возврат кортежа из кода ошибки и результата похоже на Result.

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

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

Ты уже написал 10^2 реализаций для Add? Там еще Mul и Div на очереди.

а то что проект потом в неподдерживаемом состоянии

Проект в неподдерживаемом состоянии после тебя. Достаточно посмотреть на ветку match, которая там осталась после добавления обработчика Uuid, делающего ее недостижимой.

Так что ты подтвердил мою правоту: енумы в расте важны.

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

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

Цитату, ссылку на сообщение.

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

А я отвечу. Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Ты ничего не ответил и слился, а далее при напоминаниях игнорировал.

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

Уровень познаний персонажа о С++. Бездарность, какое отношение имеет ADL к шаблонам и ошибкам компиляции? Какое отношение SFINAE имеет к ошибкам компиляции?

Siborgium ★★★★★
()
Ответ на: комментарий от fsb4000

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

Siborgium ★★★★★
()
Ответ на: комментарий от khrundel

Смотрю ничего не изменилось, ты как был д'Артаньяном так им и остался. Все вокруг идиоты, один ты на всё способен. Правда, когда доходит до дела, предлагаешь пастить код, лол.

crutch_master ★★★★★
()
Ответ на: комментарий от anonymous-angler

Нет, зачем ты пишешь чушь? match - этому мусор, убогий сахарок на switch. По крайней мере в расте. Да и в фп не лучше - там сахарок поверх иф, но там хоть иф осилили. А вот раст-огрызок нет.

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

switch используется только потому, что для него ненужно мочь в cfa. Это самый примитивный мусор. Всё. А все твои фантазии, которые придумали пропагандисты и вложили тебе в голову - к реальности отношения не имеют.

right_security
()
Ответ на: комментарий от eao197

visit мне так не позволит и в этом для меня как раз и недостаток visit-а. Ну и отсутствие overloaded сразу в stdlib :)

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

От матча отказались даже в фп-мире. Просто пародии всё ещё живут 50лет назад. Поэтому везде в нормальных фп-языках матчи описываются именно перегрузкой. В том числе для значений.

Но матчинг по значениям мусор, потому что тормозное, нерасширяемое днище годное только для фокусов.

right_security
()
Ответ на: комментарий от anonymous-angler

Зачем каждый пропагандист показывает asm? Какое отношение он к тебе имеет? Да ещё и оптимизации чужие приколхозил.

Хочешь показывать - показывай mir - это ещё можно назвать. Да и то не прокатит, потому что в llvm есть switch встроенный.

right_security
()
Ответ на: комментарий от fsb4000

Зачем это тащить в либу? Вообще какие-то рассуждение о либе - это раст/job security-пропаганда.

right_security
()
Ответ на: комментарий от Siborgium

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

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

Ты в очередной раз лжешь. От того, что ты напишешь «я тебе уже объяснил» ничего не изменится – ты слился, проблеяв про мифические мины, не приведя ни одной в пример.

Как не привёл? Я тебе вот прямо в прошлой ссылку давал. Ресолв урла через СУБД. У тебя мозги вообще не пашут?

Что характерно, именно избегая auto&& ты заложил мину с int и char.

Нет, тупица. Если написать auto&& ты, условно, получишь сообщения от компилятора в 0-50% случаев отсутствия ветки, в зависимости от того, что ты в эту ветку запишешь. Если не напишешь - получишь в 90%. До 100% ты не доведёшь никогда в виду особенностей приведения типа плюсов. Поэтому написание auto&& ситуацию ухудшает.

Мразь в очередной раз пытается проигнорировать сообщение

Ты подстелил соломку постфактум. В реальной жизни такого не происходит. Даже твой код до этого ничего подобного не содержал.

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

[](auto &&){} - - это и есть дефолтная ветка, тупица.

В принципе, на этом можно заканчивать – все ясно.А знаешь, почему не передаются? Потому что это не скейлится.

Нет, дебил ты конченый. Ещё раз, для тупых: в той же библиотеке джавы, ссылку на которую я дал как на самый конченый в плане любви к объектам язык, линия рисуется вызовом drawLine и параметрами x,y,x2,y2. Хочешь прямоугольник со скруглёнными углами - drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight). Для добавления другого примитива, авторы либы должны были бы писать новый метод drawXXX. И заметь, никакого draw(Shape shape) в этой библиотеке нет. Так устроены графические библиотеки, пока можно, они принимают простые команды, если уже нельзя - принимают сложные графические пути или модели. Вся эта срань типа class circle implements shape - её оставляют пользовательскому коду.

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

Смотрим, как он блеял о том, что до std::variant в С++ не было вариантов.

Так и не было. Говорю же тебе, клоун, буст не в счёт. Вообще. Садись, клоун, двойка, твой ответ не принимается.

Что характерно, с самого появления плюсов люди пилили свои реализации динамических массивов с реаллокацией, иногда под конкретные типы, иногда обобщённые. И все нормальные люди описывали ситуацию: «в C++ нет динамических массивов с реаллокацией, однако язык позволяет их реализовать». Потом появилась STL и ситуация сменилась на «В стандартной библиотеке плюсов есть std::vector, являющийся динамическим массивом с реаллокацией». Но почему-то для варианта вдруг должно быть по другому, вдруг факт наличия какой-то черезжопной реализации (когда не было трюка с overloaded) где-то на сайте у Васяна, которая ещё не факт что твоим компилятором подхватится, начал означать, что вариант в плюсах был ещё в нулевых.

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

Не позорься. Символьные литералы к типу char отношения не имеют.

У тебя новая версия объяснения, почему тот код скомпилялся? Зря. Я ведь, тебе, чучелу, демонстрировал, что std::variant<int,char> = 'a'; выбирает именно char-ветку в случае её наличия в visitor. Так что символьный литерал - это именно char. Ты, видимо, с K&R C спутал.

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

Нет, чучело ты тупое.

вот тебе код на go:

message, err := foo();
fmt.Println(message);

Перепиши его на «аналогичный» раст с Result.

Или, более реалистичный

message2, err2 := foo();
if err != nil {
  fmt.Println(message2);
}

Ты уже написал 10^2 реализаций для Add? Там еще Mul и Div на очереди

Ты же в курсе, что в расте есть дженерики?

Проект в неподдерживаемом состоянии после тебя. Достаточно посмотреть на ветку match, которая там осталась после добавления обработчика Uuid, делающего ее недостижимой.

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

Кроме того, та ветка могла бы остаться и по иным причинам. Вполне возможно, что в варианте есть ещё какие-то способы идентификации, которые раньше обрабатывались общей с guid веткой, потом для guid сделали оптимизированную, а старую оставили для вот них. В любом случае, обработчик «для всего» - это зло. Если лень копипастить строчки, требуй синтаксиса вида [](A&|B&|C& value){ dbaccessor.get_data(val);}.

Ты ничего не ответил и слился, а далее при напоминаниях игнорировал.

Прочитал. Теперь хотя бы понимаю, почему ты, тупица, своё СВИНАЕ вспомнил.

Что я скажу: хрень там полная и дрочево на костыли из плюсов. СВИНАЕ в расте вообще невозможен, в виду наличия нормальных дженериков. ADL… Знаешь, давай представим что это вот реально та самая сложная штука, из-за которой авторы Раст сломались, плюнули и сказали что не будут оверлоады делать. Могли бы они обойтись без неё?

Да элементарно. В расте нет, например, операторов +(a,b), оператор всегда пилится через self. Так что foo + bar для раста - это всегда foo.add(bar), так что если у тебя foo в неймспейсе, то вопросов где брать add тупо нет, в трейте, который реализован для foo.

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

Ещё раз, для тупых, оверлоады в расте есть. Они используются для определения дженерика.

trait Fooable<T> {
    fn foo(&self, a: T);
}
impl Fooable<i32> for i32 {
    fn foo(&self, a:i32){
        println!("i32 foo called")
    }
}
impl Fooable<f32> for i32 {
    fn foo(&self, a:f32){
        println!("f32 foo called")
    }
}
...
    1.foo(1f32);
    1.foo(1);

Заметь, это не дженерик функция, это разные функции, с разным кодом, и раст их легко различает.

С другой стороны, если ты добавишь:

trait Fooable2 {
    fn foo(&self);
}
impl Fooable2 for i32 {
    fn foo(&self) {
        
    }
}

то вызов 1.foo(1) перестанет компиляться и будет жаловаться на наличие 2х разных foo и требовать от тебя пояснения. Не смотря на разное число параметров. Так что мы видим сознательное решение по отключению перегрузки. Если одинаковые имена появились в виду наличия дженерика - раст соизволит найти нужную реализацию на основании параметров. Если они появились от того что случайно совпало, то раст отключает механизм перегрузки и требует написать Fooable::foo(&1, 1);

khrundel ★★★★
()
Последнее исправление: khrundel (всего исправлений: 1)
Ответ на: комментарий от khrundel

Я тебе вот прямо в прошлой ссылку давал. Ресолв урла через СУБД.

Смотрим, как мразь в очередной раз пытается проигнорировать мое

Достаточно посмотреть на ветку match, которая там осталась после добавления обработчика Uuid, делающего ее недостижимой.

Следим за руками: он специально написал код так, чтобы auto&& была недостижима на описанном варианте и была той самой else-веткой – и теперь рассказывает про то, что он ломается.

Но самое смешное здесь вообще не это. Пазл наконец-то сложился, и бездарность сама себя закопала.

[](auto &&){} – это и есть дефолтная ветка, тупица.

Можно еще немного поиграть, но я выложу все карты сразу. С++ – полиморфный язык. И [](auto && x){ resolve(x); } это не одна ветка. Это выбор из множества веток, осуществляемый по x. Здесь нет никакой «дефолтной» ветки. Именно поэтому никакие дополнительные обработчики в visit не нужны – visit нужен только для того, чтобы извлечь тип значения в варианте. Всю дальнейшую работу выполняют механизмы, ни к visit, ни к variant отношения не имеющие – те самые правила перегрузки, которые ты так и не осилил.

Ты некомпетентен.

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

template <typename T>
concept DbResolvable = requires (DbAccessor a, T t) {
    { a.get(t) } -> std::same_as<DbValue>;
};

struct None{};
struct SuperCtx{ DbAccessor& db_accessor; };

auto& get_ctx(SuperCtx& ctx, DbResolvable auto&) { return ctx.db_accessor; }
auto resolve(DbAccessor& accessor, DbResolvable auto& e) { return accessor.get(e).name; }

auto get_ctx(SuperCtx ctx, const Name&) { return None{}; }
auto resolve(None, const Name& uuid) { return name; }

auto resolve(Identifier& identifier) {
    SuperCtx ctx { db_accessor };
    std::visit([&](auto && identifier){ resolve(get_ctx(ctx), identifier); }, identifier);
}

Этот код можно разбивать на файлы как угодно. Этот код не ломается от добавления новой альтернативы. Он автоматически работает для всего, что можно разрешать через DB, и тогда точкой кастомизацией оказывается уже DbAccessor::get, перегруженный для разных типов.

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

И это не является чем-то новым для С++ – концепты это удобный синтаксис для SFINAE. Он быстрее обрабатывается компиляторами, он порождает чуть более читаемые ошибки, но не более – все то же самое можно сделать на С++11, потеряв только в выразительности.

Siborgium ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.