У меня есть два вопроса о шаблонах в C++. Предположим, что я написал простой список, и теперь я хочу использовать его в своей программе для хранения указателей на разные типы объектов (A *, B * ... ALot *). Мой коллега говорит, что для каждого типа будет создан выделенный фрагмент кода, хотя все указатели фактически имеют одинаковый размер.
Да, это эквивалентно тому, что обе функции записаны.
Некоторые линкеры обнаруживают идентичные функции и устраняют их. В некоторых библиотеках известно, что их компоновщик не имеет этой функции и учитывает общий код в одной реализации, оставляя только обтекающую оболочку вокруг общего кода. То есть, специализация std::vector<T*>
может перенаправить все работы на std::vector<void*>
, а затем выполнить кастинг на выходе.
Теперь сложная складчатость сложна: относительно легко сделать функции, которые, по вашему мнению, идентичны, но в конечном итоге не являются одинаковыми, поэтому генерируются две функции. В качестве примера игрушек вы можете уйти и напечатать имя типа через typeid(x).name()
. Теперь каждая версия функции различна, и их нельзя устранить.
В некоторых случаях вы можете сделать что-то вроде этого, думая, что это свойство времени выполнения, которое отличается, и, следовательно, идентичный код будет создан, а идентичные функции будут устранены - но умный компилятор C++ может выяснить, что вы , используйте правило as-if и включите его во время проверки времени компиляции и заблокируйте не-идентичные функции от того, чтобы быть обработанными как идентичные.
Если это правда, может кто-нибудь объяснить мне, почему? Например, в Java generics имеют ту же цель, что и шаблоны для указателей в C++. Дженерики используются только для проверки на компиляцию и удаляются до компиляции. И, конечно, один и тот же байтовый код используется для всего.
Нет, они не являются. Дженерики примерно эквивалентны методу стирания типа C++, например, std::function<void()>
для сохранения любого вызываемого объекта. В C++ стирание типа часто выполняется с помощью шаблонов, но не все использование шаблонов - стирание стилей!
То, что C++ делает с шаблонами, которые по сути не стираются, как правило, невозможно сделать с генериками Java.
В C++, вы можете создать тип стерта контейнер указателей с использованием шаблонов, но std::vector
не делает этого - он создает фактический контейнер указателей.Преимущество этого заключается в том, что проверка всех типов на std::vector
выполняется во время компиляции, поэтому нет необходимости проверять время выполнения: безопасный тип-стираемый std::vector
может потребовать проверки типа времени выполнения и связанных с ним служебных данных.
Второй вопрос заключается в том, чтобы выделенный код также был сгенерирован для char и short (учитывая, что оба они имеют одинаковый размер, и специализации нет).
Это разные виды. Я могу написать код, который будет вести себя по-другому с значением char
или short
. В качестве примера:
std::cout << x << "\n";
с й будучи short
, эта печать целого числа, значение которого x
- с x
будучи char
, это выводит символ, соответствующий x
.
Теперь почти все код шаблона существует в файлах заголовков и неявно inline
. Хотя inline
не означает, что большинство людей думает, что это означает, это означает, что компилятор может легко поднять код в вызывающий контекст.
Если это имеет значение, мы говорим о встроенных приложениях.
Что действительно имеет значение - это то, что ваш конкретный компилятор и компоновщик, и какие настройки и флаги у них активны.
как он не полностью ответил на ваш вопрос? Что он не ответил? – imulsion
'char' и' short' ** не ** имеют одинаковый размер, 'char' - 1 байт,' short' - 2 байта. – antonijn
Java Generics практически не имеют ничего общего с шаблонами C++. Возможно, кроме синтаксиса '<>. – Mat