Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Да я пока не агитирую. Интересно стало, есть ли у шаблонов в их нынешнем виде какие-либо явные преимущества перед адекватными макросами (о том, что поддерживает C/C++, вообще речи нет).
как вы не поймете, макро это — макро. а шаблоны это — щаблоны.
1. начнем еще с ассемблера да ? автоподстановка, нас с детства так учили, что такое макро. Оно так в си и задумывалось — просто генерация кода (именно генерация кода как текста) по предоставленным "шаблонам".
мы доросли до понимания, что макро либо снесут (по причине того, что оно в АСТ не попадает), либо расширят до чего-то более менее попадающего в стандарт (а не так как сейчас башеподобная кустарщина, "куда хочу так и работаю куда то втуда"), либо таки порежут. таковы тенденции
2. возмущаться плюсами можно и даже нужно, но не сильно — мешает работать. лучше сыграй на контрабасе, когда злишься, и через минуту мозговой штурм захватит тебя с такой силой, что шаблоны разлетаться будут как щепки ...
и ты поймешь что шаблоны, что контробас, что макро — инструменты для тебя любимого ) иди играйся .. ) оно прикольно. нагнешь себя любимого, потом и макро с шаблонами подогнутся.
Здравствуйте, ksandro, Вы писали:
K>ИМХО никто так не считает, просто так получилось, а что-то серьезное менять боятся.
ЕМ>>Вот будь вместо шаблонов приличный макропроцессор, в котором можно и параметры вызова разобрать, и циклические конструкции использовать, и за счет объединения с компилятором использовать в условиях типы, классы и их свойства — какие у шаблонов остались бы преимущества?
K>Ну, вот "if constexpr", который позволяет нормально выбрать условие во время компиляции вместо жутких enable_if и SFINAE в язык все таки добавили, хотя и осилили только к 17 стандарту. K>Разговоры про compile_time reflection идут давным давно, но не похоже что это скоро попадет в язык.
это потому как коммюнити слишком пассивное, и вместо консолидированного мнения выражают общее недовольство шаблонами. аля а давайте закопаем IT, все кому не нравится С++.
с моей точки зрения ct reflection уже вполне реальность, просто слишком оно коммерчески как бе так сказать. в общем если говорить серьезно
то это же прямой шаго к современной архитектуре в рамках smart solutions, кто вам такое бесплатно в стандарт вольет. всер ешается велосипедами. к примеру могу показать бранч где ребятки на llvm уже предложили compile time reflection делали точно для сових нуждд. еще лет 10-12 назад, как тут еще ремарк показывал, ну и ваш покроный слугаЮ, тоже имее тсвой солюшин по регистрации типов и по ct reflection. вещь оч удобная если отложить отдельно (чтобы не пересобиралась) для генерации инфарстуруктурных тестов, констрейнтов ..и все дешево во время компиляции.
K>Вон Саттер еще давно делал доклад о всяких метаклассах: K>www.youtube.com/watch?v=4AfRAVcThyA
K>Но никто не готов на такие радикальные перемены, потому, что нет уверенности что мы не сделаем синтаксис еще более непонятным и запутанным.
П.С. вы ка-то не совсем поняли Евгения .. )) я частично с ним согласен, и вот за раширения макро до грамматик
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>А если бы в языке изначально были условные конструкции, работающие на уровне компилятора ...
AD>Просто хочется увидеть примеры кода как всё это может выглядеть для некоторых случаев
ок
на )) я компайл тайм регекспы писал .. точно знаю, чего мне не хватает поговорим ?
П.С и вот это оно может быть скомпилировано, и запущено ... ))не ну ессно мне влом, но факт — оно запускалось.
вы пытаетесь критиковать живой код. а именно макро развиваются, и все развивается но в lazy как только критическая масса потребителей просят, и коммерчески это не невыгодно участникам рынка так оно в и впиливается к 20-му стандарту впливают __VA_OPT__ таки возможно оно поможет .. надо смотреть, что из этого выйдет. велкам в практику ))
Some compilers do allow C++20 support but do not implement the full
__VA_OPT__ support yet
так я думаю, что ct reflection не потому, что не могут. а потому, что не хотят я сейчас таки найду бранч где ребятки в boost гугл группе по SG7 в llvm реализовывали довольно уже подробно. было весьма интересно посмтреть
работать с этим не пробовал, т.к.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>При этом, изрядная доля macro hell происходила лишь от того, что обработка исходника была искусственно разделена на препроцессирование и компиляцию. В начале 70-х это еще можно было как-то оправдать нехваткой ресурсов, хотя убогие возможности сишного препроцессора вряд ли могли заметно утяжелить компилятор. Имей компилятор возможность хотя бы просто выдать в сообщении об ошибке как исходную конструкцию, так и результат ее обработки макропроцессором, это свело бы на нет бОльшую часть проблем.
В начале 70-х компилятор Си работал на PDP/11, машине с 16-битным адресным пространством. В лучшем случае, компилятору было доступно 64К для его собственного кода и 64К для данных. При этом он был достаточно умен, чтобы скомпилировать ядро первого UNIX или свой собственный текст. Сейчас в такую модель памяти не во всякой среде программирования "Hello, world!" поместится
ЕМ>Считается, что функциональный стиль использования шаблонов — это благо, но многие ли способны быстро разобраться в иерархии и взаимодействии шаблонов в какой-нибудь Boost? В конце концов, какая часть математиков интуитивно воспринимает факториал, как отображение множества целых чисел само на себя, или, на худой конец, как рекурсию, а не как последовательное (итеративное) произведение?
У C++ внутри два языка программирования, совершенно разных по стилю и парадигме. Один — сам C++, классический процедурно-императивный язык в стиле Си с классами. Другой — язык темплейтов, строго функциональный, с ленивой моделью вычисления и автовыводом типов, этакий Haskell с уродским синтаксисом.
Я думаю, многие проблемы C++ нас бы не коснулись, если бы язык темплейтов существовал бы в той же парадигме, в которой сделан сам C++.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Никакие типы выводить не нужно. Я предложил сравнить процесс обработки (во время компиляции) шаблона, в который передается переменное количество параметров, с процессом обработки (во время выполнения) кода main, в который параметры передавались бы таким же регулярным способом, что и параметры в шаблон. Реализация утилит, получающих наборы однотипных параметров разной длины, была бы несложной, зато реализация утилит с мало-мальски сложной командной строкой усложнилась бы неимоверно, а то и вовсе стала невозможной без написания отдельной процедуры для каждого набора. Именно это мы и имеем в существующем подходе к variadic.
Понял. Но у шаблонной кодогенерации и у обработки агрументов main разная цель. Записать тело класса, полученного при обработке шаблонных параметров, в процедурном стиле — это же жесть в подавляющем большинстве случаев.
ЕМ>Откуда Вы это взяли? Будь макросы предназначены исключительно для задания параметров-констант, их бы изначально ограничили до чисел, строк и идентификаторов.
Я это взял из многолетней практики и опыта других программистов. Как только начинаем передавать в макросы сложные параметры, а особенно параметры — код, или макрос сам разворачивается в сложный код, начинается ботва.
ЕМ>Да ради бога, можно вообще забыть слово "макрос", и говорить исключительно о шаблонах.
Прочитайте название темы, а теперь ваше сообщение. Никаких противоречий?
ЕМ>Если сделать возможным использование в коде шаблона условных и циклических конструкций, позволяющих анализировать как вид переданных параметров, так и их роль в программе — получится то же самое. Собственно, адекватные макропроцессоры делают именно это.
Итерировать переданные параметры в цикле? что-то типа constexpr for? Ну, может, скоро и будет. Но ничего волшебного он не даст, потому что задача шаблона — генерировать код, а средств генерировать код в подобной манере С++ не предоставляет (без выхода за проектные рамки). Как раз тут бы и понадобились именно макросы, которые могли бы ижектировать код, рассчитанный подобной функцией, в тело текста программы. Может быть, вы про это? Именно про способ генерации кода, а не про способы анализа передаваемых параметров.
Re[26]: Чем современные шаблоны лучше макросов? :)
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, night beast, Вы писали:
NB>>вроде это ты макросы продаешь
ЕМ>Я "продаю" не макросы, а идею.
Идея — ничто, реализация — всё. Идея без хотя бы MVP ничего не стоит. Тем более, что ты даже не идею продаешь, а какие-то абстрактные рассуждения. Ни на один вопрос ты не можешь в ответ показать, как бы выглядело удовлетворяющее тебя решение.
ЕМ>А главная проблема понимания — в том, что в сознании большинства программистов на C/C++ к термину "макрос" гвоздями прибито тупое, чисто лексическое преобразование, и при попытке представить себе любое другое, восприятие столь же прочно цепляется за "шаблон".
У тебя какие-то странные представления о большинстве программистов. А фантазировать — все горазды, а вот проиллюстрировать свои фантазии — это уже мало кто может. И ты тоже.
A>Если бы для С было схожее + REPL для development режима позволяющий изменять конструкции программы на лету и в частности показывать вид интерпретированных макросов, в С++ возможно не было б нужды https://www.youtube.com/watch?v=qQBpiaHXsWM
Как много веселых ребят, и все делают велосипед...
ЕМ>Вот будь вместо шаблонов приличный макропроцессор, в котором можно и параметры вызова разобрать, и циклические конструкции использовать, и за счет объединения с компилятором использовать в условиях типы, классы и их свойства — какие у шаблонов остались бы преимущества?
Шаблоны это и есть приличный макропроцессор, объединенный с компилятором.
— А вы кто?
— Я женщина вашей мечты!
— Да? Но я не о такой мечтал!
— А сбылась такая!
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ArtDenis, Вы писали:
ЕМ>>Помню, как в начале 90-х все пищали: "ах, шаблоны — это так круто и удобно, ЕМ>>...
AD>Шёл 2022 год. Народ уже давно освоил лямбды, constexpr и вариадические шаблоны, и также вовсю начал юзать async, концепты и модули... Тем временем Евгений Музыченко занялся вопросом чем шаблоны лучше макросов
У кого это была статистика что ~40% проектов на C++ имеют запрещённые исключения? И гугл тут впереди планеты всей по объёму кода с такими правилами.
Какие "async, концепты и модули"? Сколько кода с ними написано? 1%? 0.1%? 0.01%?
Я вот тут наблюдаю один вполне себе серьёзный важный проект. Уровень — C с классами. Люди — умеют свою тематику, серьёзный телеком. Геттер вида string getX() { return x_; } где "string x_"; — норма. А рядом вдруг uint8& getY() { return y_; } Const и noexcept, понятно, у обоих не стоит. Впрочем, поскольку это всё в конфигурировании (а не в hot path), всем пофиг.
Реально, "широкие народные массы" сейчас в районе C++11, не сильно выше.
Здравствуйте, netch80, Вы писали:
N>Реально, "широкие народные массы" сейчас в районе C++11, не сильно выше.
Ну я могу судить по себе только. Если новая фича что-то даёт какие-то улучшения (код проще, выразительнее, сильно короче, сильно быстрее, меньше копипасты и т.п.), то она начинает постепенно задействоваться, как только она попадает в компилятор в стабильном состоянии.
Права, недавно был в щенячем восторге от плюсового async (который мне бы пригодился в прошлом проекте ещё много лет назад). Но когда понял, что кроме удобства написания кода, он ещё даёт возможность расстреливать себе ноги автоматными очередями, загрустил и начал смотреть в сторону раста
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, netch80, Вы писали:
N>>Реально, "широкие народные массы" сейчас в районе C++11, не сильно выше.
AD>Ну я могу судить по себе только.
Ну вот это и ошибка, увы. Мы тут все оказываемся достаточно умными, чтобы сделать качественно. Это не хвастовство, увы, это констатация.
Вот на одном проекте из текущих у народа в коде дикая смесь из: табов и пробелов; LF и CRLF; почти все стили форматирования... ну и работают кто под Unix, кто под Windows, хотя целевая платформа Linux. В результате мерж оказывается почти неподъёмной задачей, что убивает кучу других параметров качества. Надо было перенести код на другую ветку без самого git (почему — это отдельный вопрос). Я на линуксе поставил core.autocrlf=true и в результате git apply прошёл, а у коллеги на Windows в тех же условиях git apply просто молча показывает "хозяин, тут делать нечего, изменений 0". В результате я ему переслал свой результат мержа (толстым архивом). Было бы больше времени, я бы поискал, почему так, но сейчас просто не до того. Ставлю вопрос форсировать политику (правилом в Jenkins), но по текущей ситуации его наверно решат через год...
Ну и код (рядом писал) в духе string getX() { return x_; } — норма.
Тем не менее проект движется, потому что 1) люди честно работают (не виноваты, что эффективность на порядок меньше нормальной, но не мухлюют) и 2) ПМы умеют в SMART или аналог.
AD> Если новая фича что-то даёт какие-то улучшения (код проще, выразительнее, сильно короче, сильно быстрее, меньше копипасты и т.п.), то она начинает постепенно задействоваться, как только она попадает в компилятор в стабильном состоянии.
Ага, а в опциях компиляции -std=c++11 и менять его не дают, потому что неизвестно, что взорвётся. Переключение на стандарт повыше это действие отдельно планируемое между ключевыми релизами и должно быть очень хорошо обосновано.
"Постепенно" — да, задействуется. Где-то в новых проектах, где-то таки убеждают догнать... но типовая 10-летняя инерция говорит, что только сейчас можно говорить, что C++11 вошёл в действительно массовое использование. И то — см. выше про исключения.
AD>Права, недавно был в щенячем восторге от плюсового async (который мне бы пригодился в прошлом проекте ещё много лет назад). Но когда понял, что кроме удобства написания кода, он ещё даёт возможность расстреливать себе ноги автоматными очередями, загрустил и начал смотреть в сторону раста
N>Я вот тут наблюдаю один вполне себе серьёзный важный проект. Уровень — C с классами. Люди — умеют свою тематику, серьёзный телеком.
Что значит "умеют"? Вызубрили порядок передачи пакетов и значения их полей при подключении клиентского устройства к провайдерскому оборудованию?
N>Геттер вида string getX() { return x_; } где "string x_"; — норма. А рядом вдруг uint8& getY() { return y_; } Const и noexcept, понятно, у обоих не стоит. Впрочем, поскольку это всё в конфигурировании (а не в hot path), всем пофиг.
Дэ, видал C++-код, написанный так называемыми "экспертами в своей области". Вполне реально было увидеть что-нибудь вроде:
так они уже достаточно допилены чтобы этот пример написать достаточно компактно, а в стандартной библиотеке так не пишут потому что:
1. она должна поддерживать и более старые стандарты, которые "еще не допилены"
2. не перепысывают из принципа "работает — не трогай"
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Тем, что существующие основаны на магии, а не на логике.
Т.е. сравнивать типы с типами это не логично и вообще какая-то магия. А вот сравнивать типы по их строковому представлению это куда как логичнее логичнее и прямее?