Как стать автором
Обновить
79
Карма
0
Рейтинг
Евгений Охотников @eao197

Велосипедостроитель, программист-камикадзе

Полиморфные структуры данных и производительность

any можно не кастовать ни к чему и оно выполнит полиморфно копирование/деструктор вас не смущает

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

Полиморфные структуры данных и производительность

Вы попробуйте подставить в мое описание вместо "A" своих "карасей", а вместо X -- свою "рыбу". А потом наоборот. И увидите, что "все караси рыбы, но не все рыбы караси". А так же и отсутствие логической ошибки, которая вам померещилась.

Полиморфные структуры данных и производительность

Нет, динамический полиморфизм это когда объект ведёт себя по разному в зависимости от своего динамического типа.

Мне непонятно почему здесь "Нет", т.к. то, что вы написали является прямым следствием того, что описал я. Ведь если за интерфейсом A в динамике обнаруживается X, то мы как раз и получаем то поведение, которое реализует именно X. Если за A стоит не X, а Y, то получим поведение от Y. Вот вам и "ведет себя по разному".

А вы описываете один единственный возможный для вас полиморфизм на виртуальных функциях.

Просто в C++ вы по другому динамический полиморфизм и не получите.

И нет, ни std::variant, ни std::any не являются примерами динамического полиморфизма в C++, т.к. вам всегда нужно знать точный тип, который вы собираетесь извлечь из std::variant/any.

Полиморфные структуры данных и производительность

На том же основании, что и ув.тов. @iCpu. Динамический полиморфизм появляется тогда, когда мы в compile-time видим лишь абстрактный базовый тип A, а в run-time у нас может появится экземпляр любого другого типа X, который удовлетворяет интерфейсу A (в терминах C++: в compile-time мы имеем базовый тип A, в run-time любой наследник от A). Причем если в контейнере лежит сразу несколько значений (v1, v2, v3, ...), то каждый из них может принадлежать любому типу наследнику X1, X2, X3, ... Причем в том числе и тем типам-наследников, которых еще не существовало в момент компиляции нашего кода с контейнером.

Полиморфные структуры данных и производительность

Прочитал статью, прочитал имеющиеся на данный момент комментарии. Увидел, что недостаточно комментариев о том, что статья не имеет отношения к динамическому полиморфизму, хотя вначале его и упоминает.

Так что этот комментарий призван исправить недостаток таких комментариев. Посему: статья не имеет отношения к динамическому полиморфизму и этот самый динамический полиморфизм вначале статьи был упомянут напрасно (либо с кликбейтной целью).

Зачем писать на C++ в 2022 году?

А вот исключение из finally — штука совершенно нормальная

Нормальная в том смысле, что не приводит к прерыванию работы приложения, так надо понимать?

Просто код finally обычные разработчики пишут так, как будто в самом finally исключения не выбрасываются поэтому можно делать действия A, B и C не заботясь о том, что каждое из них может бросить исключение.

Зачем писать на C++ в 2022 году?

Не то чтобы я очень хотел участвовать в дискуссии с

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

Он (конкретно finally/defer) должен быть если не ключевым словом, то хотя бы в стандартной библиотеке.

Не должен. finally/defer нужны языкам без детерминированого времени жизни объектов, т.к. там без finally/defer сложно детерминировано управлять ресурсами. Да и то, в Java к finally в итоге добавили try-with-resources, а в C# -- using. Так что сам по себе finally не так уж хорош.

В C++ с детерминированным управлением ресурсами все хорошо с самого начала, так что надобность в finally всегда была гораздо ниже, чем в языках с GC. В тех редких случаях, когда finally таки был нужен, можно было пользоваться паллиативами (BOOST_SCOPE_EXIT, gsl::finally и т.д.) Причем язык позволял создавать эти паллиативы на коленке. Попробуйте на коленке сделать defer для Go.

Впрочем, в C++ный стандарт сейчас так активно пихают всякое разное, что я не удивлюсь появлению finally в стандартной библиотеке где-нибудь в C++26 или C++29.

Так же, как какой-нибудь парсинг json

Вот этого не нужно. Во-первых, кроме JSON есть XML, YAML, TOML. И еще неизвестно что появится позже. Кстати говоря, лет 15 назад про JSON мало кто знал, а вот сожаления об отсутствии XML-я в stdlib высказывались. Сейчас вот XML уже не вспоминают особо, а будь он в stdlib, кому-то все бы это пришлось поддерживать.

Во-вторых, я не верю в то, что для того же JSON-а сделают библиотеку, которая одновременно будет и быстрой, и удобной в использовании. Включат в stdlib RapidJSON, будут ругать за неудобство, включат в stdlib nlohman::json, будут ругать за тормознутость.

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

функциональные литералы.

Что это такое?

Вот именно.

Вот именно что? Если для GUI вы взяли Qt а для около реалтаймовой части EASTL, то в чем собственно проблема?

Ага, а миддлы с сеньёрами размножаются клонированием. (spoiler: увы, нет)

И какой вывод из того, что они не размножаются клонированием? Дать порулить C++ным проектом джуниору?

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

А зачем вам обратный процесс? Неужели из-за того, что на Go сложно будет решать задачи, которые решаются на C++?

А давайте!

Предлагать добавить GC в C++ и жалеть об отсутствии GC в С++ в конце 2022-го года можно только от небольшого ума, уж простите. Время уже давно все расставило по своим местам: C++ с GC не нужен. Благо альтернатив с GC, хоть managed, хоть native, в достатке.

И чсх до сих пор нормально не осилили.

И не осилят. ЕМНИП, последние кусочки из стандарта, которые хоть как-то предполагали наличие опционального GC, были в конце-концов выброшены.

И да, в расте тоже нет GC, но качество управления памятью в нём просто с другой планеты.

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

Мне трудно себе представить новый (без легаси) проект на плюсах, который бы не взаимодействовал с ОС, системными либами, не использовал бы интринсики и т.д. А там везде массивы в стиле С, строки в стиле С, обработка ошибок в стиле С (вместо исключений) и так далее.

Вы не поверите, но массивы в стиле С и строки в стиле C прекрасно закрываются std::vector и std::basic_string. И обработка ошибок несложно трансформируется либо в использование исключение, либо в применение чего-то вроде std::expected.

Ну, раз дошло до личных советов, посоветую вам высунуть голову из ... норы и поинтересоваться, что там в индустрии за последние 20 лет случилось.

Да я как бы наслышан. Вот только C++, местами, все еще актуален.

А там, блин, долбаный js развивается в 10 раз быстрее плюсов.

C++ всегда развивался быстрее, чем поспевали компиляторостроители. За редким исключением в районе C++14/C++17 стандартов, когда реализация подъезжала практически одновременно с выходом фиальной версии стандарта.

А так-то уже C++20 два года назад принят, но только один компилятор сейчас его более-менее поддерживает. С принятия C++17 уже почти пять лет прошло, а в GCC/clang еще не все хорошо с поддержкой stdlib из C++17 (например, std::to_chars/std::from_chars).

И это еще не говоря о том, что в мире C++ многие еще даже на C++17 перейти не могут в силу разных обстоятельств.

Так что C++ развивается, как по мне, даже быстрее, чем хотелось бы.

Ну и да, еще на счет "за последние 20 лет случилось".

Это ведь еще сильно зависит от предметной области. Если вам в 2022-ом потребуется сделать форк Greenplum или MariaDB, заточенный под специфические нужды, или нужно будет начать делать кроссплатформенный видеоредактор, то скорость обрастания фичами JS-а или нововведения в Go вам вряд ли помогут.

Зачем писать на C++ в 2022 году?

Ну так а я о чём?

Я хз. Есть ощущение, что о том, в чем не разбираетесь.

27 строк бойлерплейта

И что? Этот бойлерплейт пишется один раз в какой-нибудь пространстве имен utils и используется по мере надобности. Причем не так часто, как вам может показаться.

В C++ это обычное дело. Точно так же было с хэш-таблицами до C++11 (да и после, т.к. std::unordered_map не всех устраивает), со string_view до C++17, с std::expected до C++23 и т.д., и т.п.

причём ну не джуниорского уровня

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

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

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

В любой программе у вас будет минимум два вида строк, минимум два вида массивов

В современных условиях такое возможно только если:

a) вы имеете дело с легаси.

b) вам реально нужны эти разные типы строк и массивов. Скажем, исходя из требований по производительности/предсказуемости.

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

Вы эти сказки таким же знатокам C++ как вы расскажите. Тогда найдете благодарную аудиторию.

На практике же приходится гуглить не какие-то особенности C++ или реализацию каких-то утилитарных вещей, а детали работы условного FFMPEG и SDL. Или пояснения к спецификациям каких-то протоколов. Или еще что-то в таком же роде, что гораздо ближе к проблемам бизнес-логики, чем отсутствие finally в языке.

Зачем писать на C++ в 2022 году?

Во всех перечисленных случаях нам нужно либо копипастить, либо создавать аж целый класс ради вызова операции В в его деструкторе, либо колхозить флаги и if-ы c goto. Сравните с finally или, особенно, с Gо-шным defer

Если вы после C++11 не можете сделать аналог Go-шного defer-а сами, то его можно взять, например, в GSL.

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

Чтобы язык помогал, его нужно освоить. Хотя бы.

Конструктор сетевых сервисов

На каком-то языке разметки описать сколько байт отправляется в какой момент и куда?

Ага.

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

Народец не тот попался, да.

Вашу разработку было бы правильнее назвать "конструктор сетевых сервисов". Хотя и здесь от слова "конструктор" могут быть неправильные ожидания.

Конструктор сетевых сервисов

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

Если вы в заголовок статьи выносите слово "конструктор", то у читателей возникают некоторые ожидания о того, какую функциональность предоставит этот самый "конструктор". И тут выясняется, что "конструктор" -- это разве что event-loop + еще несколько плюшек сверху. А всю основную работу по парсингу и валидации содержимого PDU нужно делать врукопашную.

Самое сложное это именно клиент-серверное взаимодействие, шифрование и сжатие данных

Боюсь, "у меня для вас плохие новости" (с)

Конструктор сетевых сервисов

Из этого примера мало что понятно. Вы бы вместо того, чтобы накидывать в статью 100500 разных примеров, привели бы 1-2, но с разбором того, что делается, почему делается именно так, что происходит "за кулисами".

Например, что это за методы active и message, почему у них именно такой формат, почему их нужно вручную привязывать к экземпляру sample.

Конструктор сетевых сервисов

Простите, а где, собственно, описание конструктора?

Есть примеры того, как использовать имеющийся в AWH код, написанный вами (полагаю) вручную. Если мне хочется сделать собственную реализацию какого-то протокола, который не поддерживается в AWH "искаропки", то мне придется вручную выписывать простыни кода вроде вот этой?

Или же у вас есть возможность декларативно описать a) формат PDU протокола и b) поток PDU протокола, а затем AWH для меня сгенерирует код по работе с сетью, по парсингу и проверке корректности PDU и пр.?

Упрощаем код с помощью if constexpr и концептов C++17/C++20

Почти так и сделали (цынк):

#include <type_traits>

template<typename T>
requires (std::is_same_v<T, int> 
    || std::is_same_v<T, float>
    || std::is_same_v<T, double>)
auto my_abs(T v) {
    return v < 0 ? -v : v;
}

int main() {
    my_abs(1);
    my_abs(0.1f);
    my_abs(-0.2);
    my_abs(42ul);
}

Или принципиально важно иметь именно int|float|double вместо std::is_same_v<T,int>?

Яндекс выложил в опенсорс бету фреймворка userver

Понятно, спасибо.

Надеюсь, я когда-нибудь увижу живьем программиста, который нормально владеет одновременно Ruby, Rust, JavaScript и C#.

PS. Странно что в разговоре про C++ в список языков как раз C++ и не был включен.

Яндекс выложил в опенсорс бету фреймворка userver

Возможно. И возможно об этом можно было бы даже поговорить в тяпницу, но это уже сильно выходит за рамки темы о "нормальном владении 5 языками программирования", а меня интересует именно эта тема.

Яндекс выложил в опенсорс бету фреймворка userver

На счет английского для Senior-а, да, очевидно.

А вот на счет HTML уже нет :(

Яндекс выложил в опенсорс бету фреймворка userver

В моём понимании Senior Software Engineer должен нормально владеть хотя бы 5 языками программирования

У меня, наверное, слишком завышенные требования к понятию "владеть", поэтому не очень понимаю о чем вы. Могли бы вы привести список из 5 языков для примера?

Feature freeze С++23. Итоги летней встречи комитета

Это не отменяет того факта, что С++ - сложный, и боюсь самый сложный промышленный язык, из известных мне на сегодняшний день.

Из этого вовсе не обязательно проистекает вот это:

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

Поскольку при написании прикладного кода, как правило, используются:

  • ограниченное подмножество языка;

  • готовые инструменты, скрывающие от программиста множество сложностей и нюансов.

Грубо говоря, если у вас набор хороших готовых библиотек, закрывающих вопросы вашей предметной области на 90%, то программирование на C++ не является чем-то запредельно сложным. Более того, оно даже не требует отличного знания всего (или большей части) языка.

Вот при написании подобных библиотек ситуация меняется. Грубо говоря, чтобы написать Boost.Hana или Boost.Spirit нужно знать C++ гораздо лучше, чем для того, чтобы применять их.

Но хорошие моменты в том, что:

  • разрабатывать C++ библиотеки нужно реже и высококвалифицированных C++ разработчиков для этого нужно еще меньше;

  • не обязательно делать что-то вроде Boost.Hana или Boost.Spirit с первого раза. Начинать можно и с более простых вещей, постепенно усложняя потроха по мере необходимости и приобретения опыта;

  • как раз развитие C++ с C++11 по C++17 показывает, что язык становится проще для этих целей (с C++20 пока дела не имел, не могу судить насколько он упрощает этот процесс, но те же концепты, при всей их сложности, все-таки лучше, чем бодание с SFINAE).

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

Feature freeze С++23. Итоги летней встречи комитета

На С++ приходится выводить текст программы медленно и вдумчиво

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

нигде не ошибаясь

Как это ни странно, но ошибаться нельзя ни на Java, ни на Python, ни на SQL, ни на чем-либо еще. Ошибки другого рода, конечно же, но ошибаться все равно нельзя, иначе, как в анекдоте "такая фигня получается".

Я не пытаюсь сказать, что C++ идеальный язык, но и делать из него вселенское зло, как здесь пытаются, не нужно.

Информация

В рейтинге
Не участвует
Откуда
Гомель, Гомельская обл., Беларусь
Зарегистрирован
Активность