Рубрики
Без рубрики

Шаблоны C++ и дженерики Java: два разных подхода к универсальному программированию

Различия между генерацией кода C++ и стиранием типов Java. Помеченный cpp, java, дженерики.

Универсальное программирование – это способность абстрагироваться от конкретных типов, которая впервые была представлена в 1970-х годах. Это облегчает обслуживание кода, сокращает количество избыточного кода и обеспечивает оптимизацию. Вместо того чтобы писать один и тот же алгоритм снова и снова, но каждый раз с разными типами данных, программисту нужно записать его только один раз. Например, определение size_t sum(T) вместо трех определений для size_the sum(int) , size_t сумма(длинная) , и сумма size_t(двойная) |/.

C++ допускает универсальное программирование с помощью шаблонов, которые были включены в стандарт 1998 года, но появились годами ранее в Аннотированном справочном руководстве по C++. Java позволяет универсальное программирование с помощью generics, которое было введено с Java 5 в 2004 году.

На первый взгляд они могут выглядеть одинаково, но имеют противоположные парадигмы дизайна. Шаблоны C++ используют генерацию кода, в то время как Java generics использует стирание типов.

Удаление типа удаляет тип объекта и добавляет приведение в скомпилированный байт-код. На самом деле это не добавляет ничего нового к языку. Например, как описано в Java Generics и коллекции , байт-код

List words = new ArrayList();
words.add("Hello");
String s = (String) words.get(0);

и

List words = new ArrayList<>();
words.add("Hello");
String s = words.get(0)

идентичны! Это любопытно, если синтаксис настолько отличается, почему комитет Java решил, что они должны выводить один и тот же байт-код? В конце концов, похоже, что вставка приведения и удаление типа предотвратили бы потенциальную оптимизацию.

Альтернатива заключается в том, чтобы дженерики вводили другой байт-код. Однако код, использующий дженерики и скомпилированный с помощью Java 5, больше не будет совместим с кодом, скомпилированным, написанным без дженериков до этого. Компании, которые уже использовали Java, не решались бы переходить на более новую версию. Удаление типов было компромиссом между бизнес-потребностями и улучшениями языка.

Удаление типа также гарантирует, что когда-либо будет только одна реализация универсального типа. Например, Список<Строка> , Список<Целое число> и Список все они имеют одинаковую реализацию List .

В отличие от шаблонов C++, которые были включены в стандарты с самого начала и используют генерацию кода, vector , vector и vector каждый из них имеет свою собственную реализацию. Хотя это может увеличить размер каждой единицы перевода и конечного исполняемого файла, типы, зависящие от конкретной реализации, обеспечивают программисту большую гибкость, в том числе:

  1. Специализация шаблонных функций и классов для обеспечения оптимизации. Примером может служить vector , который представляет собой экономичную по пространству версию vector

  2. Создание переменных-членов одного и того же типа. В Java стирание типов делает практически невозможным создание экземпляра переменной такого типа, как T[] T[10]; Кроме того, статические переменные-члены не могут ссылаться на универсальный тип

  3. Статический полиморфизм, такой как контейнеры STL и использование typedefs для выполнения общих операций, таких как использование итераторов

  4. Множество сложных вещей, таких как особенности политики и метапрограммирование, которые могут вычислять простые числа во время компиляции!

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

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

Оригинал: “https://dev.to/lennycheng/c-templates-and-java-generics-two-different-approaches-to-generic-programming-139i”