Компілятор буде генерувати код для кожної інстанції шаблону, коли ви використовуєте шаблон під час кроку компіляції. У процесі компіляції та зв’язування файли .cpp перетворюються на чистий об'єкт або машинний код, який у них містить посилання або невизначені символи, оскільки файли .h, які включені у ваш main.cpp, не мають реалізації. Вони готові пов’язатись з іншим об’єктним файлом, який визначає реалізацію для вашого шаблону, і таким чином у вас є повний a.out виконуваний файл.
Однак, оскільки шаблони потрібно обробити на етапі компіляції, щоб генерувати код для кожного встановленого вами шаблону шаблону, тому просто компілювати шаблон окремо від його заголовкового файлу не буде працювати, оскільки вони завжди йдуть з рук, з тієї самої причини. що кожне опитування шаблонів - це абсолютно новий клас буквально. У звичайному класі ви можете розділити .h та .cpp, тому що .h - це крок цього класу, а .cpp - це необроблена реалізація, тому будь-які файли реалізації можна збирати та зв’язувати регулярно, однак за допомогою шаблонів .h - креслення того, як клас повинен виглядати не так, як повинен виглядати об’єкт, що означає шаблон .cpp-файл не є необробленою регулярною реалізацією класу, це просто креслення для класу, тому будь-яка реалізація файлу шаблону .h може '
Тому шаблони ніколи не складаються окремо, а збираються лише там, де у вас є конкретні дані в якомусь іншому вихідному файлі. Однак конкретна інстанція повинна знати реалізацію файлу шаблону, тому що просто модифікуючиtypename T
використання конкретного типу у файлі .h не збирається виконати роботу, тому що що .cpp є для того, щоб посилатись, я не можу його знайти пізніше, тому що шаблони запам'ятовування є абстрактними і їх неможливо скласти, тому я змушений щоб дати реалізацію прямо зараз, щоб я знав, що потрібно компілювати та посилати, а тепер, коли я маю реалізацію, вона пов'язується з доданим вихідним файлом. В основному, в момент, коли я створюю шаблон, мені потрібно створити цілий новий клас, і я не можу це зробити, якщо не знаю, як повинен виглядати цей клас при використанні наданого типу, якщо я не повідомляю про це компілятора реалізація шаблону, тож тепер компілятор може замінити T
мій тип та створити конкретний клас, готовий до компіляції та зв’язування.
Підсумовуючи, шаблони - це креслення для того, як повинні виглядати класи, класи - креслення для того, як повинен виглядати об’єкт. Я не можу компілювати шаблони окремо від їх конкретної інстанції, оскільки компілятор збирає лише конкретні типи, інакше кажучи, шаблони принаймні на C ++ - це чиста абстракція мови. Ми повинні скасувати абстрактні шаблони, так би мовити, надаючи їм конкретний тип для вирішення, щоб наша абстракція шаблонів могла трансформуватися у звичайний файл класу, і, в свою чергу, він може бути складений нормально. Розмежування шаблону .h-файлу та шаблону .cpp-файла безглуздо. Це безглуздо, тому що розділення .cpp і .h є лише там, де .cpp може бути складено окремо і пов'язано окремо, з шаблонами, оскільки ми не можемо їх скласти окремо, оскільки шаблони - це абстракція,
Значення typename T
замінюється get під час кроку компіляції, а не кроком посилання, тому якщо я спробую скомпілювати шаблон, не T
будучи заміненим як тип конкретного значення, що абсолютно безглуздо для компілятора, і в результаті об'єктний код не може бути створений, оскільки він не знайте, що T
таке.
Технічно можливо створити якийсь функціонал, який збереже файл template.cpp і вимкне типи, коли він знайде їх в інших джерелах, я думаю, що в стандарті є ключове слово, export
яке дозволить вам розмістити шаблони в окремі файл cpp, але не дуже багато компіляторів реально реалізують це.
Лише бічна примітка, коли виробляються спеціалізації для шаблонного класу, ви можете відокремити заголовок від реалізації, оскільки спеціалізація за визначенням означає, що я спеціалізуюся на конкретному типі, який можна складати та зв’язувати окремо.