Ключевое отличие шаблона от макроса
От: Shmj Ниоткуда  
Дата: 09.07.23 04:18
Оценка: -1
Вот тут
Автор: rg45
Дата: 07.07.23
чел. пишет:

Дальше можно не читать. Одно только то, что ты ставишь макросы и шаблоны в один ряд, красноречиво говорит о твоей квалификации. Как говорится, у Вас не тридцатилетний опыт — у Вас годичный опыт, повторенный тридцать раз.


Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.

Вот код:

#define DECLARE_CLASS1(T) \
class Class1_##T \
{ \
public: \
    T getInc() \
    { \
        m_t += 1; \
        return m_t; \
    } \
private: \
    T m_t; \
};

DECLARE_CLASS1(int)
DECLARE_CLASS1(float)

int main() {

    Class1_int c1;
    Class1_float c2;

    c1.getInc();
    c2.getInc();
}


Это тот же шаблон класса, только с помощью макросов. И в чем ключевая разница? Что я так уж потерял?

Ну да, нужно для каждого типа написать эту строчку DECLARE_CLASS1(TTT). Это не удобно. Но по сути — синтаксический сахар. Разницы пока принципиальной нет.

Все равно каждый шаблон раскрывается в момент компиляции. Он должен быть целиком и полностью определен в заголовочном файле — нельзя разнести декларацию и дефиницию, как с обычной функцией или классом. С макросом та же проблема.

Возможно чего нельзя сделать макросами — это частичная специализация шаблонов (а может и можно придумать как). Что еще?
Re: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 06:08
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Вот тут
Автор: rg45
Дата: 07.07.23
чел. пишет:


S>

S>Дальше можно не читать. Одно только то, что ты ставишь макросы и шаблоны в один ряд, красноречиво говорит о твоей квалификации. Как говорится, у Вас не тридцатилетний опыт — у Вас годичный опыт, повторенный тридцать раз.


S>Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.


Сейчас у меня пока нет времени для подробных объяснений, попробуй почитать здесь: http://programming-lang.com/ru/comp_programming/satter/0/j33.html

Если после этого еще останутся вопросы, обсудим чуть позже.
--
Отредактировано 09.07.2023 6:10 rg45 . Предыдущая версия .
Re: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 07:26
Оценка: +5
Здравствуйте, Shmj, Вы писали:

S>Вот тут
Автор: rg45
Дата: 07.07.23
чел. пишет:


S>

S>Дальше можно не читать. Одно только то, что ты ставишь макросы и шаблоны в один ряд, красноречиво говорит о твоей квалификации. Как говорится, у Вас не тридцатилетний опыт — у Вас годичный опыт, повторенный тридцать раз.


S>Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.


Тезисно:

Первый пункт выделен, потому что он мне представляется ключевым и из него следует все остальное. Препроцессор гораздо примитивнее компилятора, его задача — подготовка текста программы для компилятора. У него на входе текст, и на выходе тоже текст. Злоупотребление препроцессором для эмуляции программных сущностей (функций и классов) является использованием инструментов не по назначению. Это сродни открыванию консервных банок молотком, или изготовлению мебели топором.
--
Отредактировано 09.07.2023 8:46 rg45 . Предыдущая версия . Еще …
Отредактировано 09.07.2023 8:44 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:43 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:41 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:40 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:34 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:17 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:16 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:08 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:48 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:47 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:30 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:27 rg45 . Предыдущая версия .
Re: Ключевое отличие шаблона от макроса
От: Pzz Россия https://github.com/alexpevzner
Дата: 09.07.23 07:32
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.


Чел. очень категоричен.

Содержательно, темплейты "понимают" язык. Макросы просто преобразуют текст.
Re[2]: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 07:49
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Чел. очень категоричен.


В чем именно я ОЧЕНЬ категоричен? В том, что макросы существенно отличаются от шаблонов по своим возможностям? Или в высказывании о том, что макросами не следует злоупотреблять? В чем конкретно?
--
Отредактировано 09.07.2023 7:53 rg45 . Предыдущая версия . Еще …
Отредактировано 09.07.2023 7:52 rg45 . Предыдущая версия .
Re: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 07:56
Оценка: 9 (1)
Здравствуйте, Shmj, Вы писали:


S>Вот код:

S>Это тот же шаблон класса, только с помощью макросов. И в чем ключевая разница? Что я так уж потерял?

Разница не очень очевидна, только благодяря примитивности примера. А ты попробуй, реализавать что-нибудь посложнее — тот же std::vector, например, или std::string, только ничего не упрощая. Или какие-нибудь метафункции из type_traits.

Попробуй, в качестве упражнения, реализовать на макросах компайл-тайм факториал, который мы недавно обсуждали. Я не говорю, что это совсем невозможно — возможно — с некоторыми ограничениями. Но это стоит сделать ради того, чтоб прочувствовать разницу.

Или еще пример, попоробуй изобразить на макросах что-нибудь наподобие Curiously Recurring Template Pattern:

template<typename UnderlyingIterator>
class MyIterator : public boost::iterator_adaptor<MyIterator<UnderlyingIterator>, UnderlyingIterator>
{
// . . .
};
--
Отредактировано 09.07.2023 13:43 rg45 . Предыдущая версия . Еще …
Отредактировано 09.07.2023 13:40 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:34 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:12 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 8:11 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:59 rg45 . Предыдущая версия .
Отредактировано 09.07.2023 7:58 rg45 . Предыдущая версия .
Re[3]: Ключевое отличие шаблона от макроса
От: Pzz Россия https://github.com/alexpevzner
Дата: 09.07.23 08:48
Оценка: +2
Здравствуйте, rg45, Вы писали:

Pzz>>Чел. очень категоричен.


R>В чем именно я ОЧЕНЬ категоричен? В том, что макросы существенно отличаются от шаблонов по своим возможностям? Или в высказывании о том, что макросами не следует злоупотреблять? В чем конкретно?


В том, что макросы существенно отличаются от шаблонов — тут ты прав. И в том, что ими не стоит злоупотреблять — тут ты тоже прав. А вот в оценке квалификации своего оппонента — очень категоричен. Вообще не понимаю, зачем было на личности переходить.

И ты учти еще такую вещь. Твой оппонент всегда работает один. Может, у него рука набита на макросах, и он в них никогда не ошибается. У него свои правила и предпочтения, выработанные с учетом его личного опыта. Когда работаешь один, это не то же самое, чем когда работаешь с другими людьми, особенно в лидерской позиции. В первом случае ты просто делаешь, как удобно именно тебе. Во втором случае, люди на тебя равняются, и не надо вносить небезопасные практики (пусть даже лично для тебя они вполне безопасные).
Re[2]: Ключевое сходство шаблона и макроса
От: LaptevVV Россия  
Дата: 09.07.23 08:50
Оценка:
Еще в 70-х была написана книга Введение в макросы. Кэмпбел-Келли М.
Вот здесь ее продают: https://www.bookvoed.ru/book?id=6716078#tdescription

В этой книжке автор определяет 3 вида макросов: текстовые, синтаксические и вычислительные (третий термин, возможно, уже попутал)
Основная операция макросов — подстановка.

Текстовый вид макросов все знают.

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

Кстати, был в свое время такой компилятор Clipper для языка Dbase II
Там в 5-й версии синтаксические макросы расцвели просто невообразимо.

Не помню про вычислительные макросы — надо перечитать.
Но в С++ есть инлайн-функции, где на место вызова функции подставляется ее тело.
Возможно, это они и есть.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Ключевое отличие шаблона от макроса
От: bnk СССР http://unmanagedvisio.com/
Дата: 09.07.23 08:59
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Вот тут
Автор: rg45
Дата: 07.07.23
чел. пишет:


S>

S>Дальше можно не читать. Одно только то, что ты ставишь макросы и шаблоны в один ряд, красноречиво говорит о твоей квалификации. Как говорится, у Вас не тридцатилетний опыт — у Вас годичный опыт, повторенный тридцать раз.


S>Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.


Зря заклеймили. Если совсем в принципе, там ведь верно написано, это все для одного и того же — для генерации кода в compile-time, функциональное программирование тут ни при чем.
Просто нормальной реализации мета-программирования, чтобы код генерировал другой код во время компиляции, и с этим было комфортно работать, пока нет, особенно в плюсах.
У плюсовых макросов полно недостатков, да и у шаблонов тоже.
Re[4]: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 10:02
Оценка: :)
Здравствуйте, Pzz, Вы писали:

Pzz>В том, что макросы существенно отличаются от шаблонов — тут ты прав. И в том, что ими не стоит злоупотреблять — тут ты тоже прав. А вот в оценке квалификации своего оппонента — очень категоричен. Вообще не понимаю, зачем было на личности переходить.


А, ты об этом... Может, и не стоило. Больно уж рассердил он меня своими предыдущими постами и воинствующим невежеством.
--
Отредактировано 09.07.2023 10:07 rg45 . Предыдущая версия .
Re[2]: Ключевое отличие шаблона от макроса
От: rg45 СССР  
Дата: 09.07.23 10:05
Оценка: :)
Здравствуйте, bnk, Вы писали:

bnk>Зря заклеймили. Если совсем в принципе, там ведь верно написано, это все для одного и того же — для генерации кода в compile-time


Макросы — это ни разу не про компайл тайм — это просто манипуляции с текстом программы, выполняемые ДО передачи этого тескта компилятору. И непонимание принципиальных различий между макросами и шаблонами — это стыдно (для того, кто претендует на звание опытного разработчика С++).
--
Отредактировано 09.07.2023 10:13 rg45 . Предыдущая версия .
Re: Ключевое отличие шаблона от макроса
От: fk0 Россия https://fk0.name
Дата: 09.07.23 10:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>

S>Дальше можно не читать. Одно только то, что ты ставишь макросы и шаблоны в один ряд, красноречиво говорит о твоей квалификации. Как говорится, у Вас не тридцатилетний опыт — у Вас годичный опыт, повторенный тридцать раз.


+1

S>Т.е. заклеймили даже за саму попытку поставить в один ряд. И мне не ясно почему.

S>
S>#define DECLARE_CLASS1(T) \
S>class Class1_##T \
S>{ \
S>public: \
S>    T getInc() \
S>    { \
S>        m_t += 1; \
S>        return m_t; \
S>    } \
S>private: \
S>    T m_t; \
S>};

S>DECLARE_CLASS1(int)
S>DECLARE_CLASS1(float)

S>int main() {

S>    Class1_int c1;
S>    Class1_float c2;

S>    c1.getInc();
S>    c2.getInc();
S>}
S>


S>Это тот же шаблон класса, только с помощью макросов. И в чем ключевая разница? Что я так уж потерял?


S>Ну да, нужно для каждого типа написать эту строчку DECLARE_CLASS1(TTT). Это не удобно. Но по сути — синтаксический сахар. Разницы пока принципиальной нет.


S>Все равно каждый шаблон раскрывается в момент компиляции.


Один раз с конкретными параметрами. А макрос -- каждый раз.

S> Он должен быть целиком и полностью определен в заголовочном файле.


Никто никому ничего не должен.

S> нельзя разнести декларацию и дефиницию,


Можно декларировать, что есть C<T>, можно отдельно дать определение, если оно нужно.
Ясно, что оно неожиданно становится нужным во многих случаях. Но точно так же и сам
класс можно отдельно объявить, что он де существует ("class name;"), а отдельно дать
определение.

S> как с обычной функцией или классом. С макросом та же проблема.


Макрос это вообще не конструкция языка. Чего сравнивать. Определение шаблона таки
компилируется до превращения в конкретный класс. А макрос -- подстановка именно текста. Любого.

S>Возможно чего нельзя сделать макросами — это частичная специализация шаблонов (а может и можно придумать как). Что еще?


Да практически всё. Начиная с того, что два макроса с одинаковыми параметрами дадут два
РАЗНЫХ класса, даже если абсолютно одинаковых по структуре. А шаблон даст один класс, в котором
в частности будет один набор static-объектов. Не говоря уж про современные нюансы, что у шаблона есть CTAD, например,
Re[3]: Ключевое отличие шаблона от макроса
От: bnk СССР http://unmanagedvisio.com/
Дата: 09.07.23 10:27
Оценка: +1
Здравствуйте, rg45, Вы писали:

bnk>>Зря заклеймили. Если совсем в принципе, там ведь верно написано, это все для одного и того же — для генерации кода в compile-time


R>Макросы — это ни разу не про компайл тайм — это просто манипуляции с текстом программы, выполняемые ДО передачи этого тескта компилятору. И непонимание принципиальных различий между макросами и шаблонами — это стыдно (для того, кто претендует на звание опытного разработчика С++).


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

Как именно производится манипуляция с исходным кодом программы — путем изменения текста, дерева (AST), во время кодогенерации, или еще как, если это хорошо, надежно и удобно работает — совершенно не принципиально.
"Метапрограммирование" на уровне изменения текста работает например в шарпе, и ничего.
Re[2]: Ключевое отличие шаблона от макроса
От: fk0 Россия https://fk0.name
Дата: 09.07.23 10:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>
  • Для макросов не предусмотрено ничего похожего на отложенное (неявное) инстанцирование, которое очень востребовано при использовании шаблонов.

    В смысле? Макросы как раз и дают результат в месте вызова, отлженно.

    R>
  • Для макросов недоступно огромное количество инструментов и паттернов, доступных для шаблонов — концепты, SFINAE, CRTP, variadic packs, template class argument deduction и пр.

    Смешаны совершенно разные концепции. SFINAЕ -- краеугольный камень, на котором всё стоит. Остальное всё
    постольку-поскольку. Переменное число аргументов есть и у макросов.

    R>
  • Макросы небезопасны в плане скрытых побочных эффектов (классический пример — max(++a, ++b))

    std::max неожиданно тоже опасен! В него можно подсунуть временнй объект.

    R>
  • Макросы существенно проблематичнее в отладке и поиске ошибок, чем шаблоны.

    Притянуто за уши. То и другое по шагам не шагается в отладчике, то и другое компиляторы умеют разворачивать
    по шагам когда показывают ошибку.
  • Re[3]: Ключевое отличие шаблона от макроса
    От: rg45 СССР  
    Дата: 09.07.23 10:43
    Оценка: +1
    Здравствуйте, fk0, Вы писали:

    R>> Макросы существенно проблематичнее в отладке и поиске ошибок, чем шаблоны.


    fk0> Притянуто за уши. То и другое по шагам не шагается в отладчике,



    Все прекрасно шагается. Да, инстанцирование шаблонных функций выполняется в компайл-тайм, но после этого по инстанцированным функциям можно спокойно ходить обычным run-time отладчиком, как по обычным функциям (если они не constexpr, конечно). Вероятно, ты путаешь constexpr функции с шаблонами функций? Так это полностью ортогональные понятия — constexpr фунцкия не обязательно должна быть шаблонной, а шаблон функции — не обязательно constexpr.
    --
    Отредактировано 09.07.2023 10:53 rg45 . Предыдущая версия . Еще …
    Отредактировано 09.07.2023 10:46 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 10:45 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 10:44 rg45 . Предыдущая версия .
    Re[4]: Ключевое отличие шаблона от макроса
    От: rg45 СССР  
    Дата: 09.07.23 10:50
    Оценка: +4
    Здравствуйте, Pzz, Вы писали:

    Pzz>И ты учти еще такую вещь. Твой оппонент всегда работает один. Может, у него рука набита на макросах, и он в них никогда не ошибается. У него свои правила и предпочтения, выработанные с учетом его личного опыта. Когда работаешь один, это не то же самое, чем когда работаешь с другими людьми, особенно в лидерской позиции. В первом случае ты просто делаешь, как удобно именно тебе. Во втором случае, люди на тебя равняются, и не надо вносить небезопасные практики (пусть даже лично для тебя они вполне безопасные).


    Если у "оппонета" столь специфичные условия работы, ему следовало бы быть более аккуратным в высказываниях. Он же постоянно норовит померить всех своим аршином, мол, "если мне не нужно, значит и другим не нужно", "если я не знаю, значит и другие не знают". Вот, недавний пример:

    http://rsdn.org/forum/cpp/8543068.1
    Автор: Евгений Музыченко
    Дата: 14.06.23

    http://rsdn.org/forum/cpp/8543075.1
    Автор: Евгений Музыченко
    Дата: 14.06.23
    .

    То, что большинство не знает о наличии в языке этой фичи, лишний раз показывает, что ее ценность околонулевая.



    Причем, пример далеко не единственный, это стиль. Он же систематически в своих постах объявляет войну всему, чего не знает, или что ему не приходилось использовать. Вроде, он какой-то эталон и язык разрабатывается только под его нужды.
    --
    Отредактировано 09.07.2023 11:06 rg45 . Предыдущая версия . Еще …
    Отредактировано 09.07.2023 11:01 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 10:57 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 10:55 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 10:51 rg45 . Предыдущая версия .
    Re[4]: Ключевое отличие шаблона от макроса
    От: rg45 СССР  
    Дата: 09.07.23 10:59
    Оценка:
    Здравствуйте, bnk, Вы писали:

    bnk>Ты говоришь о технической стороне вопроса, в привязке к плюсам. Под "генерацией кода во время компиляции" имеется в виду все, что происходит от написания кода, до его запуска.


    Нет, никто здесь не собирался обсуждать, кодгенерацию "вообще". Это конкретный форум и конкретная тема: "Ключевое отличие шаблона от макроса".

    P.S. И ключевым я считаю то, что макросы и шаблоны обрабатываются различными компонентами, несопоставимыми по сложности и своим возможностям. Я писал об ээтом здесь: http://rsdn.org/forum/cpp/8559148.1
    Автор: rg45
    Дата: 09.07.23
    --
    Отредактировано 09.07.2023 12:33 rg45 . Предыдущая версия . Еще …
    Отредактировано 09.07.2023 11:11 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 11:10 rg45 . Предыдущая версия .
    Re: Ключевое отличие шаблона от макроса
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 09.07.23 12:31
    Оценка:
    Здравствуйте, Shmj, Вы писали:

    S>Т.е. заклеймили даже за саму попытку поставить в один ряд.


    Тут дело вообще не в "попытке поставить". Просто у rg45 ко мне такая личная неприязнь, что он даже кушать не может при виде малейшего расхождения во мнениях сразу вспоминает все наши конфликты за все время присутствия здесь, и никак не упустит возможности уязвить, даже мелко и по-детски.
    Re[2]: Ключевое отличие шаблона от макроса
    От: rg45 СССР  
    Дата: 09.07.23 12:35
    Оценка: :)
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Тут дело вообще не в "попытке поставить". Просто у rg45 ко мне такая личная неприязнь, что он даже кушать не может при виде малейшего расхождения во мнениях сразу вспоминает все наши конфликты за все время присутствия здесь,


    Не так. Причину своей неприязни к тебе я объяснил здесь: http://rsdn.org/forum/cpp/8559232.1
    Автор: rg45
    Дата: 09.07.23


    ЕМ>и никак не упустит возможности уязвить, даже мелко и по-детски.


    Ну да, ну да, а ты, конечно, ведешь себя прям как взрослый тибетский монах.
    --
    Re: Ключевое отличие шаблона от макроса
    От: rg45 СССР  
    Дата: 09.07.23 13:16
    Оценка:
    Здравствуйте, Shmj, Вы писали:

    S>Он должен быть целиком и полностью определен в заголовочном файле — нельзя разнести декларацию и дефиницию, как с обычной функцией или классом.


    Вот это твое заблуждение, обусловленное недостатком знания языка. Определение шаблонов в заголовочных файлах необходимо только для неявного (implicit) инстанцирования. Но, помимо неявного, есть еще и явное инстанцирование (explicit instantiation). Шаблонные сущности (шаблоны функций и функции-члены шаблонных классов) можно не только определять в глубине единиц трансляции, но также и экспортировать из DLL.

    Суть явного инстанцирования шаблонов можно объяснить на интуитивном уровне. Вот эти строки в твоем примере, это аналог явного инстанцирования:

    DECLARE_CLASS1(int)
    DECLARE_CLASS1(float)
    --
    Отредактировано 09.07.2023 13:57 rg45 . Предыдущая версия . Еще …
    Отредактировано 09.07.2023 13:25 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 13:24 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 13:23 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 13:21 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 13:19 rg45 . Предыдущая версия .
    Отредактировано 09.07.2023 13:17 rg45 . Предыдущая версия .
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.