Подтвердить что ты не робот

Компиляция шаблонов

У меня есть вопрос, который может быть глупым, но я просто не понимаю, как это объясняется моей книгой.

В нем говорится: "Когда компилятор видит определение шаблона, он не генерирует код. Он генерирует код только при создании экземпляра конкретного экземпляра шаблона. когда мы используем шаблон (а не когда мы его определяем) влияет на то, как мы организуем наш исходный код и когда обнаруживаются ошибки... Чтобы создать экземпляр, компилятор должен иметь код, который определяет шаблон функции или функцию члена шаблона класса В результате, в отличие от кода без шаблонов, заголовки для шаблонов обычно включают определения, а также декларации.

Что именно означает "сгенерировать код"? Думаю, я никогда не думал о том, что происходит с компилятором, и на самом деле не знаю об этом, поэтому я не понимаю, что отличает, когда вы компилируете функции или классы шаблонов по сравнению с не-шаблонами

4b9b3361

Ответ 1

Компилятор генерирует код для конкретных типов, указанных в экземпляре класса шаблона.

Если у вас есть объявление класса шаблона как

template<typename T>
class Foo
{
public:
     T& bar()
     {
         return subject; 
     }
private:
     T subject;
};

как только у вас есть, например, следующие экземпляры

Foo<int> fooInt;
Foo<double> fooDouble;

они будут эффективно генерировать тот же код, что и для определенных классов, таких как

class FooInt
{
public:
     int& bar()
     {
         return subject; 
     }
private:
     int subject;
}

и

class FooDouble
{
public:
     double& bar()
     {
         return subject; 
     }
private:
     double subject;
}

и создайте экземпляры таких переменных, как

FooInt fooInt;
FooDouble fooDouble;

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

ОБНОВЛЕНИЕ:

Что делает функция члена, отличная от шаблона, быть определено вне заголовка, что функция шаблона не есть?

Объявление функции не-шаблона/члена/функции дает предопределенную точку входа для компоновщика. Определение может быть взято из одной реализации, наблюдаемой в скомпилированном объектном файле (==.cpp == блок компиляции).
Напротив, объявление шаблона класса/члена/функции может быть создано из произвольных единиц компиляции с учетом тех же или разных параметров шаблона. Определение этих параметров шаблона необходимо рассматривать хотя бы один раз. Он может быть либо общим, либо специализированным.

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

Я надеюсь, что этот пример поможет прояснить, в чем разница и усилия, прилагаемые к компилятору.

Ответ 2

Шаблон для создания кода. Когда компилятор видит определение шаблона, он делает заметки об этом шаблоне. Когда он видит использование этого шаблона, он выкапывает свои заметки, вычисляет, как применять шаблон в том месте, где он используется, и генерирует код в соответствии с шаблоном.

Ответ 3

Что должен делать компилятор, когда он видит шаблон? Создайте весь машинный код для всех возможных типов данных - ints, double, float, strings,... Может занять много времени. Или просто немного ленив и создайте машинный код для того, что ему нужно.

Я думаю, что последний вариант является лучшим решением и выполняет свою работу.

Ответ 4

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

Прямой ответ на ваш вопрос: компилятор генерирует машинный код из кода пользователя С++, я думаю, что это ват, здесь подразумевается слово "сгенерировать код".

Объявление шаблона должно быть в заголовочном файле, потому что, когда компилятор компилирует какой-то источник, в котором используется шаблон, он имеет только заголовочный файл (включен в источник с макросом #include), но ему НЕОБХОДИМО определение всего шаблона. Итак, логичный вывод состоит в том, что определение шаблона должно быть в заголовке.

Ответ 5

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

Если вы создаете шаблонную функцию, и ничто не использует шаблон (например, std:: sort), код для функции не будет сгенерирован.

Помните, что шаблоны похожи на трафареты. Шаблоны рассказывают, как сгенерировать класс или функцию с использованием заданных параметров шаблона. Если трафарет не используется, ничего не генерируется.

Считайте также, что компилятор не знает, как реализовать или использовать шаблон, пока не увидит все параметры шаблона.

Ответ 6

Я не буду сразу генерировать код. Создавайте код класса или шаблона только тогда, когда он встречается с экземпляром этого шаблона. Таким образом, если вы фактически создаете объект этого определения шаблона.

В сущности, шаблоны позволяют вам абстрагироваться от типов. Если вам нужны два экземпляра класса шаблонов, например, для int и double, компилятор будет буквально создавать два из этих классов для вас, когда они вам понадобятся. Вот что делает шаблоны настолько мощными.

Надеюсь, мое объяснение имеет смысл.

Все лучшее

Ответ 7

Ваш С++ читается компилятором и превращается в ассемблерный код перед тем, как его включить в машинный код.

Шаблоны предназначены для общего программирования. Если ваш код вообще не использует ваш шаблон, компилятор не будет генерировать связанный с ним код сборки. Чем больше типов данных ассоциируется с вашим шаблоном в вашей программе, тем больше будет генерироваться его код сборки.