Общее программирование v.s. Метапрограммирование
В чем же разница? Похоже, что термины могут использоваться несколько взаимозаменяемо, но, читая запись wikipedia для Objective-c, я наткнулся на:
В дополнение к стилю Cs процедурного программирование, С++ напрямую поддерживает определенные формы объектно-ориентированных программирование, общее программирование и метапрограммированием.
применительно к С++. Значит, они разные?
Ответы
Ответ 1
Метапрограммирование в широком смысле означает написание программ, которые дают другие программы. Например. подобные шаблоны в С++ выдает фактический код только при создании экземпляра. Можно интерпретировать шаблон как программу, которая принимает тип в качестве ввода и создает фактическую функцию/класс в качестве вывода. Препроцессор - это еще один вид метапрограммирования. Другой составленный пример метапрограммирования: программа, которая читает XML и создает некоторые SQL-скрипты в соответствии с XML. Опять же, в общем случае метапрограмма представляет собой программу, которая дает другую программу, тогда как общее программирование связано с параметризованными (обычно с другими типами) типами (включая функции).
EDITED после рассмотрения комментариев к этому ответу
Ответ 2
- Программирование: Написание программы, которая создает, преобразует, фильтрует, агрегирует и иным образом манипулирует данными.
- Метапрограммирование: написание программы, которая создает, преобразует, фильтрует, агрегаты и иным образом управляет программами.
- Generic Programming: Написание программы, которая создает, преобразует, фильтрует, агрегатирует и иным образом манипулирует данными, но делает только минимальные предположения о структуре данных, тем самым максимизируя повторное использование в широком диапазоне типов данных.
Как уже упоминалось в нескольких других ответах, различие может сбивать с толку в С++, поскольку метапрограммирование как Generic Programming, так и статическое/компиляция выполняется с помощью шаблонов. Чтобы еще больше запутать вас, Generic Programming на С++ фактически использует Metaprogramming, чтобы быть эффективными, то есть Template Specialization генерирует специализированные (быстрые) программы из общих.
Также обратите внимание, что, как знает каждый программист Lisp, код и данные - это одно и то же, поэтому на самом деле нет такой вещи, как "метапрограммирование", все это просто программирование. Опять же, это немного сложно увидеть на С++, так как вы фактически используете два совершенно разных языка программирования для программирования (С++, императивный, процедурный, объектно-ориентированный язык в семействе C) и метапрограммирование (Шаблоны, чисто функциональные "случайные" язык где-то между чистым лямбда-исчислением и Haskell с прикладом-уродливым синтаксисом, поскольку он никогда не был на самом деле предназначен для программирования.)
Многие другие языки используют один и тот же язык для программирования и метапрограммирования (например, Lisp, Template Haskell, Converge, Smalltalk, Newspeak, Ruby, Ioke, Seph).
Ответ 3
Я бы грубо определил метапрограммирование как "написание программ для записи программ" и общее программирование как "использование языковых функций для записи функций, классов и т.д., параметризованных по типам данных аргументов или членов".
В соответствии с этим стандартом шаблоны С++ полезны как для общего программирования (думаю vector
, list
, sort
...) и метапрограммирования (думаю, Boost и, например, Spirit). Кроме того, я бы сказал, что общее программирование на С++ (то есть полиморфизм времени компиляции) выполняется посредством метапрограммирования (т.е. Генерации кода из шаблонного кода).
Ответ 4
Общее программирование обычно относится к функциям, которые могут работать со многими типами. Например. функция сортировки, которая может сортировать коллекцию сравниваемых данных вместо одной функции сортировки для сортировки массива из int и другого для сортировки вектора строк.
Метапрограммирование относится к проверке, модификации или созданию классов, модулей или функций программным способом.
Ответ 5
Лучше всего смотреть на другие языки, потому что в С++ одна функция поддерживает как общее программирование, так и метапрограммирование. (Шаблоны очень мощные).
В схеме / Lisp вы можете изменить грамматику своего кода. Люди, вероятно, знают Схему как "этот язык префикса с большим количеством скобок", но также имеют очень мощные методы метапрограммирования (Hygenic Macros). В частности, можно создать try/catch, и даже грамматику можно манипулировать точкой (например, вот префикс для инфиксного конвертера, если вы больше не хотите писать префиксный код: http://github.com/marcomaggi/nausicaa). Это достигается посредством метапрограммирования, кода, который пишет код, который пишет код. Это полезно для экспериментов с новыми парадигмами программирования (оператор AMB играет важную роль в недетерминированном программировании. Надеюсь, AMB станет основным в следующие 5 лет или около того...)
В Java/С# вы можете иметь общее программирование через generics. Вы можете написать один универсальный класс, который поддерживает типы многих других классов. Например, в Java вы можете использовать Vector для создания Vector of Integer. Или Vector, если вы хотите, чтобы это было специфично для вашего собственного класса.
Когда все странно, это то, что шаблоны С++ предназначены для общего программирования. Однако из-за нескольких трюков сами шаблоны С++ завершают работу. Используя эти трюки, можно добавить новые функции на язык С++ посредством метапрограммирования. Его запутанный, но он работает. Вот пример, который добавляет несколько отправки на С++ через шаблоны. http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html. Более типичным примером является Fibonacci во время компиляции: http://blog.emptycrate.com/node/271
Ответ 6
Общее программирование - очень простая форма метакодирования, хотя обычно это не время исполнения. Это больше похоже на препроцессор в C и больше относится к программированию шаблонов в большинстве случаев использования и основных реализаций.
Вы часто найдете на типизированных языках, что вы создадите несколько реализаций чего-либо, где только тип, если он отличается. В таких языках, как Java, это может быть особенно болезненно, поскольку каждый класс и интерфейс определяют новый тип.
Вы можете сгенерировать эти классы, преобразовывая их в строковый литерал, а затем заменяя имя класса переменной для интерполяции.
Если генераторы используются во время выполнения, это немного отличается, в этом случае это просто переменное программирование, программирование с использованием переменных.
Способ предусмотреть, что это просто, взять в файлы, сравнить их и превратить что-то другое в переменную. Теперь у вас есть только один файл, который можно использовать повторно. Вам нужно указать только то, что отличается от переменной name.
Как появились обобщения, что не все может быть изменено, как тип переменной, который вы ожидаете, или тип броска. Часто было много дублирования файлов, где единственной переменной, которая была переменной, были типы переменных. Это был очень распространенный источник дублирования. Хотя есть способы обойти это или смягчить, они не особенно удобны. Дженерики пришли как разновидность переменной, чтобы позволить переменную типа переменной. Поскольку тип переменной - это что-то, что обычно выражается на языке программирования, которое теперь можно указать во время выполнения, оно также считается метакодированием, хотя и очень простым.
Эффект отсутствия изменчивости там, где вам нужно, - это развернуть ваши переменные, то есть вы вынуждены, вместо того чтобы иметь переменную, чтобы сделать реализацию для каждого возможного значения переменной.
Как вы можете себе представить, это довольно дорого. Это было бы очень распространено при использовании любой библиотеки хранения объектов повторного использования. Они будут принимать любой объект, но в большинстве случаев люди хотят только ранить один тип objdct. Если вы добавите объект Shop, который расширяет Object, а затем хотите его получить, подпись метода на объекте хранения будет возвращать просто Object, но ваш код ожидает объект Shop. Это сломает компиляцию с понижением уровня объекта, если вы не вернете его обратно в магазин. Это вызывает еще одну загадку, так как без дженериков нет возможности проверить совместимость и гарантировать, что объект, который вы храните, является классом магазина.
Java избегает метапрограммирования и пытается сохранить язык простым, используя принципы полиморфизма ООП, вместо этого, чтобы сделать гибкий код. Однако есть некоторые насущные и повторяющиеся проблемы, которые через опыт представили и рассматриваются с добавлением минимальных средств метапрограммирования. Java не хочет быть языком метапрограммирования, но редко импортирует концепции оттуда для решения самых вопиющих проблем.
Языки программирования, которые предлагают средства метакодирования для лаважа, могут быть значительно более производительными, чем языки, чем избегать его, запрещающего специальные случаи, отражения, полиморфизма ООП и т.д. Однако часто требуется гораздо больше навыков и знаний, чтобы генерировать un = nderstandable, maintaiable and ошибка. Также часто наблюдается снижение производительности для таких языков, когда С++ является немного странным, потому что он скомпилирован для native.