Альтернативы шаблонам C++?

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

Однако я думаю, что шаблон C++ сосет потому что:
1. они замедляют время компиляции (даже с предварительно скомпилированными заголовками, которые заканчивают тем, что были 50 МБ, больших, если среди Вас какой-либо из него материал STL).
2. они дают ужасный компилятор/синтаксические ошибки, которые являются counintuitive
3. они не были разработаны для сложного метапрограммирования во-первых (генерирующий comipler ошибки для простых чисел / показывающими шаблонами является завершенный Тьюринг, было грандиозное предприятие назад в день).

Сказав все это, там достойная альтернатива для метапрограммирования C++? что-то как

*.m-> метакомпилятор-> *.cpp-> g ++-> исполняемый файл?

Править:

Я думаю вроде "сценариев поколений пользовательского кода". Я просто задаюсь вопросом, существует ли действительно хороший набор их там.

6
задан BЈовић 15 October 2011 в 19:59
поделиться

4 ответа

Я не уверен, что это то, что нужно захотеть, я использовал генераторы кода для получения кода C ++. В частности, Python Cheetah. Вы взимательно встроили прямой код Python в код C ++ и пробегаете через Preprocessor Cheetah Preprocessor.it позволяет делать довольно сложные вычисления намного проще, чем использование шаблонов или препроцессора C ++, плюс вы получаете все библиотеки и расширения Python. С другой стороны, он делает отладку сложнее, если что-то пойдет не так. Если вы заинтересованы, я мог бы предоставить некоторые примеры и режим Emacs для редактирования программ Cheetah C ++.

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

Хорошо, я вставил пример гепарда, дай мне несколько минут:

#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
        for(int a = 0; a < $N; ++a) {
            /// for functions in block
%for ii, (fi,fj) in enumerate(fb)
%set i = ii + ifb
/// can also use (ix,iy,iz)=fi[0:2], need to clean up when not lazy
%set ix = fi[0]
%set iy = fi[1]
%set iz = fi[2]
%set jx = fj[0]
%set jy = fj[1]
%set jz = fj[2]
            q$(i) += Ix(a,$(ix),$(jx))*Iy(a,$(iy),$(jy))*Iz(a,$(iz),$(jz));
%end for
            /// end for functions in block
        }

производит (после бега Гепарк ... )

#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
        for(int a = 0; a < 6; ++a) {
            q0 += Ix(a,0,1)*Iy(a,0,0)*Iz(a,0,0);
            q1 += Ix(a,1,1)*Iy(a,0,0)*Iz(a,0,0);
            q2 += Ix(a,0,1)*Iy(a,1,0)*Iz(a,0,0);
            q3 += Ix(a,0,1)*Iy(a,0,0)*Iz(a,1,0);
            q4 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,0,0);
            q5 += Ix(a,1,0)*Iy(a,0,1)*Iz(a,0,0);
            q6 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
            q7 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
            q8 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
            q9 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
        }

, который является обычным C ++ кодом

строки, начинающиеся с%, интерпретируются как утверждения Python Preprocessor Cheetah. /// Гепард комментарии. По умолчанию используйте # в качестве утверждений Python, но я изменил их, чтобы избежать столкновения с директивами с Cre Preprocessor. % End должен использоваться для преобразования блоков Python. Переменные в C ++ код, начнут с $, заменяется переменными Python.

Вы хотите примеры, используя повышение препроцессора?

7
ответ дан 8 December 2019 в 17:21
поделиться

Генерация кода - лучший ответ ...

Вы также должны посмотреть, как Kernel Linux имеет связанные списки.

Linux Kernel Связанный список пояснил

Основная идея заключается в том, что вместо того, чтобы ваш тип встроен в некоторую структуру (скажем, следующие и предыдущие указатели, для типичного реализации списка), у вас есть структура списка ядра, встроенная в свой структурой ... вид изгнания разума, но проверьте статью ... Я никогда не думал, что тип безопасные дженерики были возможны в C пока я не увидел это ....

2
ответ дан 8 December 2019 в 17:21
поделиться

Если вы используете C ++, я думаю, что ваши единственные жизнеспособные альтернативы - это либо прямые макросы препроцессора , либо пользовательская генерация кода .

Описанный вами рабочий процесс в основном представляет собой некоторую форму генерации кода, при которой вы предварительно обрабатываете свой .m-файл в компилируемый код на C ++. SWIG - действительно хороший пример проекта, который делает это.

Лично я имел большой успех в написании генераторов кода на Python, но я думаю, что любой язык сценариев был бы столь же хорош. Один из пакетов, который может быть полезен, - это cog от нашего собственного Неда Батчелдера :)

1
ответ дан 8 December 2019 в 17:21
поделиться

Большинство людей настаивают на попытке метапрограммирования изнутри своего любимого языка. C++ приводится в качестве квинтэссенциального примера из-за метапрограммирования шаблонов. Хотя это работает, это болезненно и неуклюже. Я нахожу показательным тот факт, что люди догадались, что он поддерживает Тьюринга, после того, как Строустроп добавил его в язык; я не думаю, что даже он ожидал, что все получится именно так, как получилось, хотя я сомневаюсь, что он стал бы жаловаться на это сейчас.

Но большинство языков программирования не имеют средств метапрограммирования. (Или они могут иметь слабые или неуклюжие возможности:)

Способ обойти это - сделать метапрограммирование из вне языка, используя инструменты преобразования программ. Такие инструменты могут анализировать исходный код и выполнять в нем произвольные преобразования (именно это в любом случае делает метапрограммирование), а затем выплевывать переработанную программу.

Если у вас есть система преобразования программ общего назначения, которая может разбирать произвольные языки, вы можете выполнять метапрограммирование на любом языке. Смотрите наш DMS Software Reengineering Toolkit для такого инструмента, который имеет надежные передние части для C, C++ (даже C++17), Java, C#, COBOL, PHP и ряда других языков программирования, и был использован для метапрограммирования на всех этих языках.

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

И преобразование программ является более мощным, чем метапрограммирование шаблонов C++, несмотря на то, что TM способен по Тьюрингу! Причина в том, что TM может генерировать произвольный код из шаблонов, но не может модифицировать нешаблонный код. Программные преобразования могут имитировать TM, если вы настаиваете, и поэтому они, по крайней мере, столь же сильны, но они также могут выполнять произвольные изменения нешаблонного кода. Таким образом, строго более мощный.

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

(Мы провели архитектурный реинжиниринг очень больших приложений C++ с помощью DMS. TM просто не может этого сделать).

4
ответ дан 8 December 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: