Здравствуйте, alpha21264, Вы писали:
A>Эк тебя корёжит! A>Это не тролинг. A>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.
и где ты там один бит углядел?
ну а по сути, твое предложение сводится к реализации std::variant собственными силами.
Здравствуйте, night beast, Вы писали:
A>>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.
NB> NB>и где ты там один бит углядел?
bool successful ; // Да, я знаю, что компилятор тут использует целый int, но это не мои проблемы.
NB>ну а по сути, твое предложение сводится к реализации std::variant собственными силами.
Дааааааааа? Вот уж не знал! И нахрена мне std::variant, да ещё "собственными силами"?
Где? Зачем? Что такое std::variant? Как жили без std::variant? Почему до сих пор без него живут?
Здравствуйте, alpha21264, Вы писали:
A>Эк тебя корёжит!
Желание общаться конструктивно теперь называется "корёжит"? Ok.
A>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.
Для начала укажем на то, что вы проигнорировали тот важный факт, что successful_result_t и failed_result_t -- это не пустые структуры. В них есть свои собственные поля, значения которых важны. Причем, чтобы разговор был интереснее, давайте сделаем так, чтобы эти поля не пересекались. Т.е., пусть будет:
struct successful_result_t {
A a_;
B b_;
C c_;
... // Конструктор/деструктор и пр. лабуда.
};
struct failed_result_t {
D d_;
E e_;
... // Конструктор/деструктор и пр. лабуда.
};
Покажите, пожалуйста, как вы собираетесь в своем подходе передавать в reply_t либо содержимое successful_result_t, либо содержимое failed_result_t.
По поводу bool successful_ -- садитесь, двойка. Еще одна подобная шутка и будете признаны профнепригодным, а значит, и не диалогоспособным.
Хотя бы уж enum class result_t { success, failure }. Его и расширять можно, и контроль со стороны компилятора гораздо лучше.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, so5team, Вы писали:
S>>Вы вместе с вашими матерыми C++ разработчиками вместо этого предлагаете что?
E>Это, кстати, хорошее упражнение. Представить, что шаблонов нет, или что свои нельзя писать и подумать, как написать тоже самое без шаблонов.
Да сколько угодно, писать на Cи, а это будет именно Си, с классами, RAII и прочей шелухой, что в Си различными фреймворками реализуется в крупных проектах, вроде ядер, вообще просто. Проще чем на С++, что означает развитие системы абстракций в виде множества параметризованных обобщённых типов и взваимосвязей между ними. Короче, С++-это когда структурирование и обобщение в помощью шаблонов, если этого нет, то это Си с классами.
Здравствуйте, alpha21264, Вы писали:
A>Где? Зачем? Что такое std::variant?
type-safe union XXI-го века. Пора вылазить из криокамеры.
A>Как жили без std::variant?
Не жили. Использовали либо union, либо делали свои лисапеды с преаллоцированными буферами, placement new и ручным вызовом деструкторов.
A>Почему до сих пор без него живут?
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, alpha21264, Вы писали:
A>>bool successful ; // Да, я знаю, что компилятор тут использует целый int, но это не мои проблемы.
X>
Сам дурак.
Ты не фейспалмы раскидывай, а давай рассказывай, почему тут нельзя обойтись одной единственной переменной.
Здравствуйте, alpha21264, Вы писали:
A>Сам дурак.
тебя в хлеву воспитывали?
A>Ты не фейспалмы раскидывай, а давай рассказывай, почему тут нельзя обойтись одной единственной переменной.
я лишь указал на то, что bool это не int, а байт. по-крайней мере я не слышал о платформе с восьмибитными интами...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, alpha21264, Вы писали:
A>>Эк тебя корёжит!
S>Желание общаться конструктивно теперь называется "корёжит"? Ok.
Там не было желания общаться конструктивно.
A>>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.
S>Для начала укажем на то, что вы проигнорировали тот важный факт, что successful_result_t и failed_result_t -- это не пустые структуры. В них есть свои собственные поля, значения которых важны. Причем, чтобы разговор был интереснее, давайте сделаем так, чтобы эти поля не пересекались. Т.е., пусть будет: S>
struct successful_result_t {
S> A a_;
S> B b_;
S> C c_;
S> ... // Конструктор/деструктор и пр. лабуда.
S>};
S>struct failed_result_t {
S> D d_;
S> E e_;
S> ... // Конструктор/деструктор и пр. лабуда.
S>};
S>
Я сделаю вот так:
struct result_t {
bool successful ;
A a_;
B b_;
C c_;
D d_;
E e_;
// Конструктор/деструктор и пр. лабуда.
};
По жизни в 90% случаев result_t будет содержать ТОЛЬКО данные успешного завершения.
Данных неуспешного завершения не будет вообще (поэтому многие вместо ошибки вообще возвращают NULL).
В остальных 10% случаев данные неуспешного завершения разместятся в тех же полях, что и успешного.
А если совсем-совсем жалко места (ну это совсем скупердяем надо быть) мы умеем использовать слово union.
S>Покажите, пожалуйста, как вы собираетесь в своем подходе передавать в reply_t либо содержимое successful_result_t, либо содержимое failed_result_t.
Передавать я буду как обычно:
функция( Результат );
или
return Результат ;
У меня же один тип результата, а не два как у Вас.
Поэтому мне не нужно решать тех проблем, которые есть в случае с темплейтами.
S>По поводу bool successful_ -- садитесь, двойка. Еще одна подобная шутка и будете признаны профнепригодным, а значит, и не диалогоспособным.
Сам дурак.
S>Хотя бы уж enum class result_t { success, failure }. Его и расширять можно, и контроль со стороны компилятора гораздо лучше.
Зачем Вы опять делаете навороты на ровном месте?!
Когда НАДО будет я расширю bool на enum.
Но заранее-то это зачем делать?
bool студенты проходят в школе, это заранее известная конструкция,
а за enum class result_t надо лезть в то место, где она описана.
Q>На С++. Чтобы создать качественную симуляцию, надо разбираться в том, как организовать детект коллизий, солвер контактов и констрейнтов, вычислительно устойчивую интеграцию, etc. Можно ли его назвать неквалифицированным программистом? А между тем там не то что шаблонов, там даже RAII толком нет, голый Си с классами и прости господи сырыми указателями, плюс-минус использование std::vector'а какого-нибудь. Зато движок легко читать и понимать, и можно не приходя в сознание портировать на любой JavaScript.
Тут в треде не говорится о том, должен ли чего-то знать разраб кроме ЯП-а, или нет, конечно должен. Кучу всего. Вернее, уметь быстро изучать ту или иную предметную область, попав на проект, необходимую для текущего проекта, так как всё знать невозможно, а проекты могут быть самые разные, от REST сервисов до нейронки. И ЯП-ов он должен знать не один а с десяток. Тут речь о том, как именно писать на C++, чтоб это можно было назвать кодом на C++, а не на Си с классами, и это безотносительно каких-либо иных знаний и компетенций.
Здравствуйте, smeeld, Вы писали:
S>Тут речь о том, как именно писать на C++, чтоб это можно было назвать кодом на C++, а не на Си с классами, и это безотносительно каких-либо иных знаний и компетенций.
Называй как хочешь. C++ и есть С с классами, а не нечто сверхестественное — за это многие его и ценят. Вместо шаблонов почти всегда достаточно использовать полиморфизм, как уже упоминал Qbit86.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, alpha21264, Вы писали:
S>>Желание общаться конструктивно теперь называется "корёжит"? Ok.
A>Там не было желания общаться конструктивно.
По вашим сообщениям с фразами "Сам дурак" и "Ну это я прикололся" было заметно, что у вас нет желания общаться конструктивно.
A>>>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.
A>Я сделаю вот так: A>
A>struct result_t {
A> bool successful ;
A> A a_;
A> B b_;
A> C c_;
A> D d_;
A> E e_;
A>// Конструктор/деструктор и пр. лабуда.
A>};
A>
Ожидаемо. Сейчас даже не будем говорить за оверхед по памяти/времени, т.к. в данном конкретном случае это не существенно.
Как вы собираетесь обеспечить гарантии того, что в случае неудачного результата программист не будет обращаться к полям a_, b_ и c_.
Ну а тема дальнейшего расширения набора результатов в вашем подходе вообще открывает какие-то бездны фейспалма.
A>А если совсем-совсем жалко места (ну это совсем скупердяем надо быть) мы умеем использовать слово union.
Судя по тому, что вы уже написали, вы вряд ли можете что-то использовать что-то сложнее bool-а и int-а.
A>Поэтому мне не нужно решать тех проблем, которые есть в случае с темплейтами.
И какие же это проблемы?
A>Зачем Вы опять делаете навороты на ровном месте?!
Здравствуйте, so5team, Вы писали:
A>>Где? Зачем? Что такое std::variant?
S>type-safe union XXI-го века. Пора вылазить из криокамеры.
Зачем тебе в данном случае type-safe? Мне и в камере хорошо.
A>>Как жили без std::variant?
S>Не жили. Использовали либо union, либо делали свои лисапеды с преаллоцированными буферами, placement new и ручным вызовом деструкторов.
В данном случае union-а хватит до конца жизни вселенной.
A>>Почему до сих пор без него живут?
S>Разве это жизнь?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
lpd>>Вместо шаблонов почти всегда достаточно использовать полиморфизм, как уже упоминал Qbit86.
S>Интересно было бы посмотреть на type-safe union без шаблонов на полиморфизме.
В 98% случаев абсолютно все равно, сколько структура занимает памяти — сейчас не 1Mb памяти на все, и многие вообще пишут на Java.
В твоем примере можно просто reply_success_t и reply_failure_t унаследовать от reply_t, и этого достаточно для реализации любой логики. Либо result_success_t и result_failure_t унаследовать от result_t. В крайнем случае использовать union для полей, но только если это действительно необходимо.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
S>>Интересно было бы посмотреть на type-safe union без шаблонов на полиморфизме.
lpd>В 98% случаев абсолютно все равно, сколько структура занимает памяти — сейчас не 1Mb памяти на все, и многие вообще пишут на Java.
В том-то и дело, что там, где не важно потребление ресурсов, спокойно пишут на Java/Scala/Kotlin/Ceylon, C#/F#/VisualBasic, Python, Ruby и даже, как говорят, на Haskell-е. Место для C++ осталось там, где важно иметь контроль за происходящим.
lpd>В твоем примере можно просто reply_success_t и reply_failure_t унаследовать от reply_t, и этого достаточно для реализации любой логики.
Во-первых, *_resul_t специально отделены от reply_t. Т.к. там, где получается *_result_t, никто ничего не знает о reply_t.
Во-вторых, логика будет усложнена за счет того, что придется ловить не один reply, а два разных (а потом, возможно и больше).
lpd>Либо result_success_t и result_failure_t унаследовать от result_t.
И передавать их как? Через unique_ptr?
lpd>В крайнем случае использовать union для полей, но только если это действительно необходимо.
C union-ом все становится интереснее как только туда помещаются данные с нетривиальными деструкторами. И тогда сразу же возникает вопрос: чем это лучше std::variant?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
S>В том-то и дело, что там, где не важно потребление ресурсов, спокойно пишут на Java/Scala/Kotlin/Ceylon, C#/F#/VisualBasic, Python, Ruby и даже, как говорят, на Haskell-е. Место для C++ осталось там, где важно иметь контроль за происходящим.
Я сторонник того, чтобы оптимизировать алгоритм, а код оставлять максимально простым и понятным. Для оптимизации все равно union и ассемблер сильнее, чем шаблоны и компилятор.
lpd>>В твоем примере можно просто reply_success_t и reply_failure_t унаследовать от reply_t, и этого достаточно для реализации любой логики.
S>Во-первых, *_resul_t специально отделены от reply_t. Т.к. там, где получается *_result_t, никто ничего не знает о reply_t.
Я имел ввиду либо базовый result_t, либо базовый reply_t — не обязательно оба вместе. S>Во-вторых, логика будет усложнена за счет того, что придется ловить не один reply, а два разных (а потом, возможно и больше).
Отличие только в том, что с использованием полиморфизма для result_successful_t и result_failure_t нужно будет добавить один базовый класс: result_t. Мне такой путь нравится больше шаблонов, хотя похоже, что это вопрос предпочтений.
Для удобства можно добавить в result_t поле enum с кодом возврата.
lpd>>Либо result_success_t и result_failure_t унаследовать от result_t.
S>И передавать их как? Через unique_ptr?
Умные указатели я считаю только усложняющими управление памятью, хотя это оффтоп. Передавать просто через указатель "result_t *" — это самое простое.
S>C union-ом все становится интереснее как только туда помещаются данные с нетривиальными деструкторами. И тогда сразу же возникает вопрос: чем это лучше std::variant?
reply_t и result_t обычно простые классы. У тебя есть указатель на result_t. В result_failure_t определен деструктор. Не вижу сложностей.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Я сторонник того, чтобы оптимизировать алгоритм, а код оставлять максимально простым и понятным.
Ну надо же. В какую сторону вы еще разговор уведете вместо того, чтобы показать type-safe union без шаблонов на полиморфизме?
lpd>Для оптимизации все равно union и ассемблер сильнее, чем шаблоны и компилятор.
Правда?
lpd>Я имел ввиду либо базовый result_t, либо базовый reply_t — не обязательно оба вместе.
Это понятно. Только вы, очевидно, не отдаете себе отчет о том, как будет меняться код в одном и другом случае. Приходится вам это объяснять.
lpd>Отличие только в том, что с использованием полиморфизма для result_successful_t и result_failure_t нужно будет добавить один базовый класс: result_t. Мне такой путь нравится больше шаблонов, хотя похоже, что это вопрос предпочтений.
Ну так напишите хотя бы приблизительный код. Сразу станет видно и его объем, и его надежность, и его понятность.
S>>И передавать их как? Через unique_ptr? lpd>Умные указатели я считаю только усложняющими управление памятью, хотя это оффтоп. Передавать просто через указатель "result_t *" — это самое простое.
Т.е. мы создаем result в динамической памяти? Дергаем хип и создаем лишнюю косвенность там, где можно было обойтись передачей/перемещением значения.
А потом, что вообще прекрасно, отдаем кому-то владеющий голый указатель в надежде на то, что кто-то когда-то его удалит?
Етить-колотить, казалось, что в мире C++ подобные взгляды на управление памятью уже в дикой природе не встречаются, только в каких-то особых замкнутых заповедниках. А поди ж ты.
lpd>reply_t и result_t обычно простые классы.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, lpd, Вы писали:
lpd>>Отличие только в том, что с использованием полиморфизма для result_successful_t и result_failure_t нужно будет добавить один базовый класс: result_t. Мне такой путь нравится больше шаблонов, хотя похоже, что это вопрос предпочтений.
S>Ну так напишите хотя бы приблизительный код. Сразу станет видно и его объем, и его надежность, и его понятность.
Писать код чтобы продемонстрировать полиморфизм, и его отличия от шаблонов? Открой любую книжку по C++ начала 200х. Сферический обработчик reply_t интереса не представляет, т.к. все зависит от деталей использование этих объектов.
S>>>И передавать их как? Через unique_ptr? lpd>>Умные указатели я считаю только усложняющими управление памятью, хотя это оффтоп. Передавать просто через указатель "result_t *" — это самое простое.
S>Т.е. мы создаем result в динамической памяти? Дергаем хип и создаем лишнюю косвенность там, где можно было обойтись передачей/перемещением значения.
Ну все, фанатика move-семантики я переубедить не берусь. Все-таки подумай о том, что из использования C++ в требовательных к ресурсам проектах не значит, что любая операция в программе на C++ должна быть обязательно соптимизирована move-семантикой. А для тех очень редких операции, которые все-таки нужно оптимизировать, можно сделать пул объектов.
S>А потом, что вообще прекрасно, отдаем кому-то владеющий голый указатель в надежде на то, что кто-то когда-то его удалит? S>Етить-колотить, казалось, что в мире C++ подобные взгляды на управление памятью уже в дикой природе не встречаются, только в каких-то особых замкнутых заповедниках. А поди ж ты.
В каждом конкретном случае такую проблему можно решить без умных указателей — вариантов решений много, включая подсчет ссылок. Хотя от полноценного GC польза была бы.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)