Из разных сравнений среди шаблонов C ++ и C # / обобщений Java, как этот
У меня сложилось впечатление, что шаблоны C ++ реализуются с помощью некоторой предварительной обработки (замена простого текста перед синтаксическим анализом), а не компиляции. Потому что проверка типов в шаблонах C ++ напоминает макросы C. Я имею в виду, что если есть какие-то ошибки, это ошибки в сгенерированном коде после обработки шаблонных блоков кода, а не в самих шаблонах. Другими словами, они являются своего рода верхней версией макросов в C.
Затем я нашел некоторые другие факты, подтверждающие это
Я думал, что если шаблоны C ++ будут реализованы с помощью предварительной обработки, возникнут проблемы с динамическим связыванием (с использованием .dll). И быстрый поиск в Google поддержал это.
Другое дело, что целочисленные константы могут быть переданы в качестве аргументов шаблонам. И это даже поддерживает какую-то рекурсию. Но эта рекурсия не найдена в скомпилированной сборке / машинном коде. Управление рекурсией осуществляется во время компиляции путем генерации функций для каждого рекурсивного вызова и, таким образом, получения большего, но более быстрого исполняемого двоичного файла.
Хотя в отличие от макросов C, он обладает некоторыми превосходными возможностями. Но разве шаблон C ++ не реализован с какой-то предварительной обработкой? Как это реализовано в разных компиляторах C ++?
Ответы:
Шаблоны C ++ являются своего рода тупыми макросами Lisp (или даже более того, Scheme). Это полный по Тьюрингу язык, который оценивает во время компиляции, но он сильно ограничен, так как у него нет доступа к базовой среде C ++. Итак, да, шаблоны C ++ можно рассматривать как некую форму предварительной обработки, с очень ограниченным взаимодействием с генерируемым кодом.
источник
Вероятно, самое большое отличие состоит в том, что макросы C расширяются на этапе предварительной обработки, прежде чем будет выполнена какая-либо другая компиляция, в то время как шаблоны C ++ являются частью компиляции. Это означает, что шаблоны C ++, помимо прочего, учитывают тип и ограничены областью применения и не являются простой текстовой заменой. Они могут компилироваться в реальные функции и, следовательно, избегать большинства проблем, возникающих в макросах. Понимание типов означает, что они могут быть общими или специализированными: например, легко обеспечить функцию
swap
шаблона и легко написать специализации, которые хорошо работают, даже если объекты управляют кучей памяти.Следовательно: шаблоны C ++ не подвергаются предварительной обработке в том же смысле, что и макросы, они не являются своего рода макросом C, и невозможно использовать макросы C для дублирования того, что делают шаблоны.
Шаблоны живут в заголовочных файлах, а не в связанных библиотеках, правда, но если вы предоставляете .dll, вы, вероятно, также предоставляете файл заголовка для его использования.
источник
export
реализованы. Я знаю, что это работает для функций, но я сомневаюсь, что это работает для классов: как бы вы узнали их размер?Имеет ли значение, как они реализованы? Ранние компиляторы C ++ были просто препроцессорами, которые передавали код в компилятор ac, это не значит, что C ++ - просто прославленный макрос.
Шаблоны устраняют необходимость в макросах, предоставляя более безопасный, более эффективный и специализированный (даже я не думаю, что это настоящее слово) способ реализации кода для нескольких типов.
Существует множество способов создания шаблонов кода типов в c, и ни один из них не очень удобен, если вы выходите за рамки простых типов.
источник
Есть некоторые различия; например, шаблоны могут использоваться для создания экземпляра перегрузки функции, когда это необходимо, в то время как с макросами вам придется расширять макрос один раз для каждой возможной перегрузки, чтобы сделать его видимым для компилятора, так что вы получите много неиспользованного кода.
Другое отличие состоит в том, что шаблоны уважают пространства имен.
источник
ИМХО, шаблоны C ++ и макросы C предназначены для решения двух совершенно разных задач. Исходная библиотека стандартных шаблонов C ++ представляла собой механизм для чистого отделения контейнерных классов (массивов, связанных списков и т. Д.) От универсальных функций, обычно применяемых к ним (таких как сортировка и конкатенация). Наличие абстрактных представлений эффективных алгоритмов и структур данных приводит к более выразительному коду, потому что было значительно меньше догадок о том, как лучше всего реализовать функцию, работающую с конкретным фрагментом данных. Макросы C были в большей степени соответствуют тому, что обычно можно увидеть в макросах Lisp, в том смысле, что они предоставляли средство для «расширения» языка с помощью встроенного кода. Круто то, что стандартная библиотека C ++ расширила функциональность шаблонов, чтобы охватить подавляющее большинство того, для чего мы используем #define в C.
источник