Здравствуйте, Pzz, Вы писали:
Pzz>Может, у него рука набита на макросах
Я ими не злоупотребяю. Обычно использую там, где шаблон либо не даст нужного эффекта, или где вместо простого макроса пришлось бы городить (или подключать снаружи) невнятную шаблонную конструкцию, результаты развертывания которой нужно будет изучать по ассемблерному листингу, чтоб не нарваться на сюрпризы.
Pzz>и он в них никогда не ошибается.
Покажите мне того, кто никогда не ошибается хоть в макросах, хоть в шаблонах.
Но надо сказать, что за всю практику, на поиск косяков в макросах я потратил гораздо меньше времени, чем на поиск косяков в шаблонах.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Но надо сказать, что за всю практику, на поиск косяков в макросах я потратил гораздо меньше времени, чем на поиск косяков в шаблонах.
Здравствуйте, bnk, Вы писали:
bnk>нормальной реализации мета-программирования, чтобы код генерировал другой код во время компиляции, и с этим было комфортно работать, пока нет, особенно в плюсах.
Есть, только не в плюсах. Самое навороченное, что я видел — макропроцессор ассемблера OS/360. Чуть менее наворочен был макропроцессор PL/1. А потом это как-то резко сошло на нет, хотя макропроцессор уровня Macro-11 или TASM уделывает убогий сишный на раз.
Вообще, сама идея принудительного разделения обработки исходника на макропроцессирование и компиляцию — редкостное извращение, и не может быть оправдана даже малым количеством ресурсов в начале 70-х. Большинство тогдашних компиляторов (куда более сложных, чем первые версии C) прекрасно обходилось без отдельной фазы, за счет чего было реализовано много удобных и полезных плюшек. Ресурсы, потребные на макрообработку, скромны даже на фоне компиляции с простейшего C, а уж на фоне C++ они и вовсе ничтожны. А это дурацкое разделение на фазы, возведенное в парадигму, и заблокировало многие пути совершенствование макропроцессора, и породило великое множество ошибок, вызванных непониманием сути процесса.
Здравствуйте, Евгений Музыченко, Вы писали:
bnk>>нормальной реализации мета-программирования, чтобы код генерировал другой код во время компиляции, и с этим было комфортно работать, пока нет, особенно в плюсах.
ЕМ>Есть, только не в плюсах. Самое навороченное, что я видел — макропроцессор ассемблера OS/360. Чуть менее наворочен был макропроцессор PL/1. А потом это как-то резко сошло на нет, хотя макропроцессор уровня Macro-11 или TASM уделывает убогий сишный на раз.
Это какие-то реликты
Я имел в виду, чтобы:
— работало автодополнение, когда пишешь макрос, в контексте кода.
— была возможность нормальной отладки, то есть чтобы можно было например ставить точки останова и ходить по шагам, во время компиляции.
Здравствуйте, bnk, Вы писали:
bnk>Это какие-то реликты
Так я ж говорю — почему-то сошло на нет. Возможно, сперва возобладали идеи вроде синтаксических шаблонов, а когда обнаружилась функциональная полнота плюсовых шаблонов, у идеологов окончательно снесло крышу в этом направлении, и они тупо перестали воспринимать все, что выбивается из этой концепции. Собственно, и здесь многие на этом зациклены — "все, что может быть реализовано на шаблонах, должно быть реализовано на них, невзирая на сложность и затраты ресурсов на компиляцию, ибо это правильно".
bnk>- работало автодополнение, когда пишешь макрос, в контексте кода.
Так это ж свойство редактора, язык тут ни при чем. Разве что редакторам удобно пользоваться API компиляторов для анализа текста (как минимум, VS так делает), а при таком подходе все ломает пресловутая двухэтапная концепция.
bnk>- была возможность нормальной отладки, то есть чтобы можно было например ставить точки останова и ходить по шагам, во время компиляции.
Это было бы нетрудно реализовать и при разделении фаз, но куда удобнее было бы иметь макропроцессор в составе компилятора.
Здравствуйте, Shmj, Вы писали:
S>Это тот же шаблон класса, только с помощью макросов. И в чем ключевая разница? Что я так уж потерял?
В отличии от макросов, которые генерируют код, шаблоны сами являются кодом. Соответственно, на шаблонах можно написать то, что не возможно на макросах без шаблонов.
Самый простой приходящий сегодня мне в голову пример — это запрет чего-либо для всех типов, за исключением указанных.
Допустим у нас есть вот такой код:
void fun(int n)
{
std::cout << "n=" << n << '\n';
}
int main()
{
int n = 1;
fun(n); // n=1float f = 2.1;
fun(f); // n=2return 0;
}
— при выводе f преобразовалось в int и вывод получился не верный.
Я не вижу способа предотвратить такое поведение без шаблонов.
С помощью шаблона можно предотвратить такое поведение. Следующий код не компилируется:
void fun(int n)
{
std::cout << "n=" << n << '\n';
}
template <class T>
void fun(T) = delete; // forbid all implicit conversionsint main()
{
int n = 1;
fun(n); // n=1float f = 2.1;
fun(f); // error: use of deleted function ‘void fun(T) [with T = float]’return 0;
}
Здравствуйте, LaptevVV, Вы писали:
LVV>Синтаксические макросы — это подстановка на этапе компиляции с проверкой получившегося синтаксиса. LVV>Как все, надеюсь, понимают, шаблоны — это разновидность синтаксических макросов по классификации Кемпбела-Келли.
Не совсем.
Шаблоны участвуют в системе типов.
Шаблон класса не просто принимает на вход набор аргументов, подставляет что-то куда-то и выдаёт AST некой структуры с полями, именами и прочим добром.
Он ещё и тип этой структуры определяет.
И ещё он несёт информацию о своих аргументах, что позволяет сопоставлять их и извлекать — с помощью других шаблонов.
Шаблон функции участвует в перегрузках и задаёт приоритет (нешаблонные перегрузки предпочтительнее шаблонных, специализации предпочтительнее основного шаблона).
Это несколько выходит за рамки функций над AST, не так ли?
LVV>Кстати, был в свое время такой компилятор Clipper для языка Dbase II LVV>Там в 5-й версии синтаксические макросы расцвели просто невообразимо.
О да! И, насколько помню, он прямо с самого начала был макроязыком над дубасей.
Но при этом что-то ни у кого не возникало попыток хотя бы чисто академических накатить на клиппер арифметику Пеано или ещё какую-нибудь такую фигню.
Был ли он тьюринг-полным? Ой сомневаюсь.
Ну, может, в пятой версии прикрутили фич?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Есть, только не в плюсах. Самое навороченное, что я видел — макропроцессор ассемблера OS/360. Чуть менее наворочен был макропроцессор PL/1. А потом это как-то резко сошло на нет, хотя макропроцессор уровня Macro-11 или TASM уделывает убогий сишный на раз.
Так-то к сям пытались прикрутить внешний препроцессор m4.
Не взлетело.
Для всякой ерунды по мелочи — хватает сишного препроцессора.
"А если он чего-то не может, — это вам не нужно" (с) Стив Джобс
ЕМ>Вообще, сама идея принудительного разделения обработки исходника на макропроцессирование и компиляцию — редкостное извращение, и не может быть оправдана даже малым количеством ресурсов в начале 70-х. Большинство тогдашних компиляторов (куда более сложных, чем первые версии C) прекрасно обходилось без отдельной фазы, за счет чего было реализовано много удобных и полезных плюшек. Ресурсы, потребные на макрообработку, скромны даже на фоне компиляции с простейшего C, а уж на фоне C++ они и вовсе ничтожны. А это дурацкое разделение на фазы, возведенное в парадигму, и заблокировало многие пути совершенствование макропроцессора, и породило великое множество ошибок, вызванных непониманием сути процесса.
Куда более сложные компиляторы работали на куда более сложных машинах. PL/I сделали для IBM 360, а для PDP-11 что-то не потянули.
Так что дело именно в экономии ресурсов.
А потом уже — в гигантском легаси.
Здравствуйте, Кодт, Вы писали:
К>Так-то к сям пытались прикрутить внешний препроцессор m4. К>Не взлетело.
Закономерный итог почти любой попытки заменить убогое и примитивное сразу на неимоверное и развесистое.
К>Для всякой ерунды по мелочи — хватает сишного препроцессора. К>"А если он чего-то не может, — это вам не нужно" (с) Стив Джобс
Вот его б совсем чуть-чуть до ума довести, и дальше уже особо не надо. Увеличения ресурсоемкости никто б и не заметил.
Здравствуйте, Shmj, Вы писали:
S>Возможно чего нельзя сделать макросами — это частичная специализация шаблонов (а может и можно придумать как). Что еще?