Комментарии 55
Очень интересный способ. Но на его написание (ИМХО) уйдёт больше времени, чем на вычисление массива первой функцией и его вывода в буфер обмена.
↑Ненормальное программирование↑
↑Ненормальное программирование↑
+2
Ну, на написание данной вещи действительно ушло много времени. Но теперь есть навык, такое же можно писать очень быстро. Но, как вы правильно замтеили, это же блог «Ненормальное программирование».
+2
Когда от приложения требуется добиться высокой производительности, то проще программисту потратить n-ое кол-во времени, чем приложение потратит на его выполнение в целом. Давно использую данный подход в php, очень доволен. Правда не знал как он называется. Хотя конечно на С++ реализовать такой подход значительно сложнее.
0
А чем это выгодно? Программа стартует на несколько миллисекунд быстрее, зато нагородили кучу темплейтов ради такой простой вещи.
-3
Эти темплейты закрываются внутри пространства имен и снаружи не видны. Вообще говоря это — proof of concept, ничего более.
+4
а более реалистичный пример можно? с одно стороны метапрограммирование — это прекрасное упражнение для мозгов, но с другой — я не понимаю, где оно может дать серьезные бенефиты.
у template metaprogramming есть на мой взгляд лишь один плюс перед подходом основанном на кодогенерации: шаблоны являются частью языка. На мой взгляд этот плюс убивается мозговзрывающей сложностью более или менее серьезного шаблона.
у template metaprogramming есть на мой взгляд лишь один плюс перед подходом основанном на кодогенерации: шаблоны являются частью языка. На мой взгляд этот плюс убивается мозговзрывающей сложностью более или менее серьезного шаблона.
0
Прерасный пример! :) Замечательный!
И дело не в том, сколько ДАННЫЙ пример выигрывает или сколько ДАННЫЙ пример экономит.
Это замечательный пример того, как вычисления можно перенести на стадию компиляции!
И дело не в том, сколько ДАННЫЙ пример выигрывает или сколько ДАННЫЙ пример экономит.
Это замечательный пример того, как вычисления можно перенести на стадию компиляции!
+5
Класс! Отдельное спасибо автору за указание книги, где о таком пишут.
Правда, страшно представить отладку такого нагромождения темплейтов. Там одну букву не так поставишь, оно такого насчитает… и внутрь не заглянешь step-by-step, ещё и темплейты с их способностью выдавать 20 errors на одну опечатку. Программирование тут, может, и ненормальное, но отладка (особенно, если применить для чего-то более сложного) уже за гранью ненормального. «Madness? This is SPARTAAA!!!» :)
Правда, страшно представить отладку такого нагромождения темплейтов. Там одну букву не так поставишь, оно такого насчитает… и внутрь не заглянешь step-by-step, ещё и темплейты с их способностью выдавать 20 errors на одну опечатку. Программирование тут, может, и ненормальное, но отладка (особенно, если применить для чего-то более сложного) уже за гранью ненормального. «Madness? This is SPARTAAA!!!» :)
0
спасибо, люблю магию :)
+2
Жесть!!! Мы в микроконтроллерах все CRC табличным способом считали, да еще и выискивали где бы микросекунду сэкономить :-)
+1
НЛО прилетело и опубликовало эту надпись здесь
На самом деле всё выглядит столь ужасно потому, что метапрограммирование в C++ не добавили, а открыли. Случайно. В языках где про него изначально думали (D, Scala, разнообразные диалекты Lisp'а) всё горазло менее страшно. Но принцип тот же: программа порождает программу.
+4
НЛО прилетело и опубликовало эту надпись здесь
Ну там добавят немножко новых возможностей. Основная, cамая вкусная, фича классических языков с поддержкой метапрограммирования всё так же далека: язык метапрограммирования не является вариантом языка программирования. Он совершенно иной! А должен быть тем же — ну пусть с небольшими ограничениями. Вот тогда метопрограммирование становится удобным инструментом, а не игрушкой для фанатов…
0
В Scala (пока) нет метапрограммирования.
+1
люблю такой стиль программирования (вернее ненавижу:) пришлось как-то развивать/улучшать систему для расчетов генераторов для ветрянных электростанций. Генераторов таких (медленновертящихся, без «коробки передач») никто не делал, программист-дипломант до меня наворотил там целый язык из макросов и шаблонов для описания формул. Бедные инженеры для изменения формулы правили код, потом компилировали его (занимало примерно 10 минут) а потом тестировали свою формулу. И так весь день, ругались постоянно, так как настройка была сплошной потерей времени. Ну и мне пришлось повозиться, беда.
В общем, в этом деле нужно чувство меры, и не всегда время потраченное на компиляцию оправдывает быстроту работы программы, не говоря уже о проблеме «ремонтопригодности» такой штуки.
В общем, в этом деле нужно чувство меры, и не всегда время потраченное на компиляцию оправдывает быстроту работы программы, не говоря уже о проблеме «ремонтопригодности» такой штуки.
0
Это да. Такие вещи, серпя сердце, можно применять только в хорошо известных алгоритмах — как в данном случае. Сам бы за такое давал по пальцам. Но эти знания, почерпнутые из книги Александреску, подвигли меня на изучение хотя бы основ функционального программирования, и эти знания мне очень пригодились при переходе на C# 3.5, LINQ, лямбды и иже с ними.
0
Ага, функциональное программирование это вещь:) Но лично для меня даже в лиспе (а именно доктор схеме) ламда была не совсем «читабельна».
На данный момент реализация в груви мне лично нравится больше всего, синтакс (лично мне) хорошо понятен, хотя на данный момент я с груви не работаю.
На данный момент реализация в груви мне лично нравится больше всего, синтакс (лично мне) хорошо понятен, хотя на данный момент я с груви не работаю.
0
а SICP уже читали?
на русском можно скачать здесь — sicp.sergeykhenkin.com/
на русском можно скачать здесь — sicp.sergeykhenkin.com/
+1
Интересное решение, а как изменилось время компиляции?
0
Естественно упала. На пару-тройку секунд.
0
Как раз после прочтения книги Александреску появилось чуство что С++ не мое.
Потому что жутко не нравится время компиляции и совсем не радует его увеличение библиотеками Loki, Boost. С STL приходиться мириться.
После довольно жуткого проекта с временем полного ребилда пять минут и убитой архитектурой (ребилдить приходилось часто) переметнулся к динамическим языкам.
Теперь занимаюсь Python, Ruby, PHP, JavaScript.
PS: Кодогенерация есть в Qt — qmake. Интересно почему такие системы не получили распространения?
Имхо, кодогенерация шаблонами не гибка, многословна и даже не кеширует результат.
PSS: Python + Qt — отличная связка.
Потому что жутко не нравится время компиляции и совсем не радует его увеличение библиотеками Loki, Boost. С STL приходиться мириться.
После довольно жуткого проекта с временем полного ребилда пять минут и убитой архитектурой (ребилдить приходилось часто) переметнулся к динамическим языкам.
Теперь занимаюсь Python, Ruby, PHP, JavaScript.
PS: Кодогенерация есть в Qt — qmake. Интересно почему такие системы не получили распространения?
Имхо, кодогенерация шаблонами не гибка, многословна и даже не кеширует результат.
PSS: Python + Qt — отличная связка.
+2
А я сижу на динамических языках и очень грущу о С++ и C# :)
Кстати, а зачем вообще нужен полный ребилд? У нас так только night builds собирались для автотестов.
Кстати, а зачем вообще нужен полный ребилд? У нас так только night builds собирались для автотестов.
0
Кстати да, тоже советую всем почитать книгу Андрея Александреску «Современное проектирование на С++».
К счастью, у большинства людей эта книга отбивает желание писать сложные шаблоны :) Зато дает навык их понимания.
Книга сложная, но правильная. И кроме сложных случаев метапрограммирования, там есть еще отличные примеры более простых шаблонов, например Policy-based дизайн классов.
К счастью, у большинства людей эта книга отбивает желание писать сложные шаблоны :) Зато дает навык их понимания.
Книга сложная, но правильная. И кроме сложных случаев метапрограммирования, там есть еще отличные примеры более простых шаблонов, например Policy-based дизайн классов.
-1
Да, меня в свое время поразили возможности, открываемые шаблонами в C++. Пример замечательный.
-1
Помнится, игрался я в школе с метапрограммированием
www.everfall.com/paste/id.php? c29q3eov4cjj — определитель матрицы N*N compile-time
www.everfall.com/paste/id.php? zakx0n2nwaaa — мультиметоды (для N <= 32 аргументов, а не только для 2)
Вообще, язык метапрограммирования в Си++ — чистый функциональный, но, к сожалению, без карринга и лямбд.
В новом стандарте должны ввести concept/concept_map — в чистом виде type classes из Haskell
www.everfall.com/paste/id.php? c29q3eov4cjj — определитель матрицы N*N compile-time
www.everfall.com/paste/id.php? zakx0n2nwaaa — мультиметоды (для N <= 32 аргументов, а не только для 2)
Вообще, язык метапрограммирования в Си++ — чистый функциональный, но, к сожалению, без карринга и лямбд.
В новом стандарте должны ввести concept/concept_map — в чистом виде type classes из Haskell
0
Метапрограммирование слабо применимо в коммерческой разработке, если конечно же код пишет не Александреску :)
— Это увеличивает время компиляции. Т.е. сначала я трачу деньги компании на поиск не тривиального решения времени комспиляции, затем я трачу деньги компании на перекомпиляции всего этого добра.
— Это увеличивает сложность проекта, т.е. после ухода человека проектировавшего ЭТО, сложно будет найти настолько же подкованного.
— Применение подобных приемов в языке, который не был спроектирован для этого — не самое лучшее занятие.
Более того, это действительно не продуктивно. Я прочел Александреску два раза, причем оба раза некоторые вещи я читал до посинения и полного понимания. В итоге через два года я практически ничего не помню, и понимания кода выше мне дается с большим трудом, может потому, что было мало практики. Но для сравнения, QT после года использования я не забыл и прекрасно помнил. Так что сложность таки сказывается.
— Это увеличивает время компиляции. Т.е. сначала я трачу деньги компании на поиск не тривиального решения времени комспиляции, затем я трачу деньги компании на перекомпиляции всего этого добра.
— Это увеличивает сложность проекта, т.е. после ухода человека проектировавшего ЭТО, сложно будет найти настолько же подкованного.
— Применение подобных приемов в языке, который не был спроектирован для этого — не самое лучшее занятие.
Более того, это действительно не продуктивно. Я прочел Александреску два раза, причем оба раза некоторые вещи я читал до посинения и полного понимания. В итоге через два года я практически ничего не помню, и понимания кода выше мне дается с большим трудом, может потому, что было мало практики. Но для сравнения, QT после года использования я не забыл и прекрасно помнил. Так что сложность таки сказывается.
+5
Давнишний тред на rsdn про метапрограммирование — читать и помнить.
+3
А вот пример для определения простых чисел: sharpc.livejournal.com/23950.html
Только, хочу обратить внимание на слова автора и свой личный опыт: если «разворачивание» метаконструкций будет достаточно долгим, то компилятор выдаст ошибку.
Только, хочу обратить внимание на слова автора и свой личный опыт: если «разворачивание» метаконструкций будет достаточно долгим, то компилятор выдаст ошибку.
0
(вернее, прекомпилятор)
Какой такой «прекомпилятор»?
0
пропроцессор.
0
сомневаюсь, что препроцессор таким занимается.
0
Та часть компилятора, которая отвечает за шаблоны и константы. :)
0
Именно он этим и занимается.
0
да ну? может потрудитесь доказать?
я вот более чем уверен, что препроцессор не занимается вычислением константных выражений.
я вот более чем уверен, что препроцессор не занимается вычислением константных выражений.
0
у препроцессора свой метапрограмминг :)
#define tType uint64_t
#define tName(n) myname_#n
#include «t/MetaProg.tpl»
… t/MetaProg.tpl
struct tName(mystruct) {
tType x;
};
void tName(myfun)() {
что-нибудь делаем;
}
#undef tType
#undef tName
#define tType uint64_t
#define tName(n) myname_#n
#include «t/MetaProg.tpl»
… t/MetaProg.tpl
struct tName(mystruct) {
tType x;
};
void tName(myfun)() {
что-нибудь делаем;
}
#undef tType
#undef tName
0
Класс! Побольше бы именно таких топиков, а не «Oh shi, это же новый айфон!».
Автор, спасибо Вам.
Автор, спасибо Вам.
+7
НЛО прилетело и опубликовало эту надпись здесь
Спасибо, занимательно. Но если мне не изменяет мой склероз, конкретно этот пример соптимизирует компилятор ((= По крайней мере GCC.
0
Отличный пост! Хорошо что не перевелись ещё computer science! Скажем да шаблону и нет былокодингу :)
0
«цикла, повторяющего вычисления «рекурсивно» 7 раз» — исправьте
0
Еще одно уточнение: таблица все же заполняется в runtime, но значения таки считаются на этапе компиляции. Статья понравилась, спасибо.
0
Таблица тоже заполняется в компайлтайм, потому как инициализация константная и инлайнится.
0
ОМГ!
P.S.
За код и пояснения — примите благодарность :)
P.S.
За код и пояснения — примите благодарность :)
0
Самое интересное, что GCC и Comeau это не компилируют. Они считают что:
identifier «values» is undefined
Table() { values[t]=Hash:: value; }
identifier «values» is undefined
Table() { values[t]=Hash:: value; }
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Публикации
Изменить настройки темы
Метапрограммирование в C++