У чому різниця між класом шаблону та шаблоном класу?


85

У чому різниця між класом шаблону та шаблоном класу?

Відповіді:


125

Для багатьох це загальна плутанина (включаючи сторінку загального програмування у Вікіпедії, деякі підручники з C ++ та інші відповіді на цій сторінці). Що стосується С ++, то не існує поняття "клас шаблону", існує лише "шаблон класу". Спосіб прочитати цю фразу - це "шаблон для класу", на відміну від "шаблону функції", який є "шаблоном для функції". Знову ж таки: класи не визначають шаблони, шаблони визначають класи (і функції). Наприклад, це шаблон , зокрема шаблон класу , але це не клас :

template<typename T> class MyClassTemplate
{ 
    ...
};

Декларація MyClassTemplate<int> є класом, або педантично, класом на основі шаблону. Немає особливих властивостей класу на основі шаблону порівняно з класом, який не базується на шаблоні. Особливі властивості самого шаблону .

Фраза "шаблон-клас" нічого не означає, оскільки слово "шаблон" не має значення як прикметник, коли застосовується до іменника "клас", що стосується С ++. Це передбачає існування класу, який є (або визначає) шаблоном , який не є поняттям, що існує в C ++.

Я розумію загальну плутанину, оскільки вона, мабуть, базується на тому, що слова з’являються у порядку "клас шаблону" фактичною мовою, що зовсім інша історія.


+1. Іноді корисно з якихось причин розрізнити "походження" класу, і в цьому випадку ви можете обґрунтовано використовувати термін "клас-шаблон" - але з причин, які ви вказали, гарною ідеєю є ретельно визначити, що ви маєте на увазі під цим .
j_random_hacker

1
@j_random_hacker - див. відповідь litb нижче, але коротше, кращим терміном для цього є "спеціалізація на шаблоні класів"
Не впевнений

@ Не впевнений: Ну насправді я вважаю "спеціалізацію шаблону класу" дещо неоднозначним, оскільки вона також може стосуватися процесу визначення явної або часткової спеціалізації для шаблону - того, що не потрібно для створення фактичного "класу". :) IMHO "створення шаблону класу" - найбільш чіткий термін.
j_random_hacker

2
@j_random_hacker: Для цього є відповідний термін - "явна спеціалізація шаблону класу" та "часткова явна спеціалізація шаблону класу.". Громіздкий, але не двозначний :)
Не впевнений

1
-1 Терміни означають те, що вони означають для людей, що використовують терміни. Починати аналіз буквальних значень безглуздо. Просто спробуйте практично будь-яким іншим терміном з повсякденного життя чи техніки. Підводячи підсумок, ця відповідь - фігня. Відповідь SHH , цитуючи Бьярна, є нормальною.
Вітаю і hth. - Альф

13

Б'ярн Страуструп, творець С ++, у своїй книзі Мова програмування С ++ 4-е видання , 23.2.1 Визначення шаблону:

Є люди, які роблять семантичні відмінності між шаблоном класу термінів та класом шаблону . Я не; це було б занадто тонко: будь ласка, вважайте ці терміни взаємозамінними. Подібним чином, я вважаю шаблон функції взаємозамінним з функцією шаблону .


12

Різниця полягає в тому, що термін «клас шаблону» просто не існує в Стандарті C ++. Цей термін використовується переважно тими людьми, які вважають, що термін "шаблон класу" заплутаний (наприклад, компанії Qt Nokia та колишня Trolltech).

Стандарт не має поняття, тому інші люди мають змінити ситуацію. Деякі люди використовують його синонімічно, а інші кажуть, що термін «клас шаблону» відноситься до інстанційованого або явно спеціалізованого шаблону класу, що робить його еквівалентним терміну «спеціалізація шаблону класу». Історично це мало таке значення. У Annotated Довідкове керівництво визначає на сторінці 343

Клас, згенерований із шаблону класу, називається класом шаблону, як і клас, спеціально визначений із іменем шаблону-класу як його ім'я

Нетермінальний шаблон-ім'я-класу еквівалентний нетермінальному ідентифікатору шаблону, що використовується в сьогоднішньому стандарті, і падає template-name < arguments >.


Ознайомити вас із сьогоднішніми термінами, що важливіше, ніж використовувати сумнівні старі терміни

// (1) defines a class template
template<typename T> class A { }; 

// (2) defines a class template explicit specialization 
template<> class A<int> { };

// (3) defines a class template partial specialization
template<typename T> class A<T*> { };

// (4) explicitly instantiates A<char>. 
template class A<char>;

// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
  • ARM назвав клас (2), а класи, породжені (4) та (5), шаблоном класу . Я не впевнений, чи ARM вже знав про часткову спеціалізацію. Але якщо це так (3) не називався класом шаблону, оскільки (3) не визначає клас, а визначає шаблон.
  • Поточний стандартний виклик класу (2) та тих, що генеруються спеціалізаціями шаблонів класів (4) та (5) . І (3) називається частковою спеціалізацією , на відміну від явної спеціалізації . Це також іноді називає (3) спеціалізацію (3,2 / 5 - однак із уточненням перехресних посилань), хоча я вважаю, що це мені не зовсім зрозуміло, оскільки вона визначає "спеціалізацію" як "клас, функцію або клас член ", що (3) не задовольняє.

3
Хе-хе. Так, і ще кілька людей також все ще сприяють цьому набору. Зокрема C ++ Faq lite і документація Qt. Автор faq lite сказав мені поштою, що хоче розмістити ще один розділ поширених запитань, пояснюючи, що краще використовувати слово "спеціалізація", оскільки воно викликає менше плутанини (використання "явної спеціалізації" для виду спеціалізації, написаного користувачем, тоді). Хлопці Qt сказали мені, що не хочуть використовувати термін "шаблон класу" .... вони вважають це занадто "неприродним". Шкода.
Йоханнес Шауб - літ

@ JohannesSchaub-litb: ARM написали Бьярн Страуструп та Маргарет Елліс, приблизно 1991 року, IIRC. Ваша цитата з ARM суперечить цитаті SHH з 4-го видання TCPPL Бьярна . Тож добре, що ви розрізнили стару (достандартну) та сучасну термінологію.
Вітаю і hth. - Альф


1

Шаблон класу - це шаблон, який використовується для генерації класів, тоді як шаблон класу - це клас, який створюється шаблоном.


0

Клас шаблону: Клас, що має загальне визначення, або клас із параметрами, який не створюється, поки інформація не надається клієнтом. Це називається жаргоном для простих шаблонів. Простий клас із шаблоном префіксу та використанням T. Шаблон класу: Індивідуальна конструкція класу визначається шаблоном класу, який майже подібний до способу побудови окремих об’єктів за допомогою класу. Він посилається на об'єкт класу шаблону Ex-classname ім'я об'єкта (список аргументів)


0

Шаблон класу - це загальний клас для різних типів об’єктів. В основному він забезпечує специфікацію для генерації класів на основі параметрів. Щоразу, коли створюється новий об'єкт, для цього в пам'яті буде відбуватися новий клас. Це називається створенням екземпляра шаблону класу, а кожна інстанційована версія класу називається шаблоном класу.


0

Погляньте на цю статтю (з wg21 та опублікована в 1992 році) :

Послідовна термінологія

Багато суперечок та розбіжностей на сьогоднішній день стосувалося термінології, використаної в главі, що описує шаблони. Найбільш частим було різне застосування 'function-template' та 'template-function' для вираження різних ідей та намірів. Оскільки не застосовується послідовне іменування, результатом є плутанина та аргументація.

Для цілей цього документу, як пропозицію щодо офіційного прийняття комітетом під час обговорень шаблонів та для уточнення документації; Я пропоную прийняти формалізацію, що кінцевий '-template' описує набір типів або функцій, описаних шаблоном. І що провідний 'template-' використовується для опису визначення шаблону частини '-template' , наприклад 'template-member-function'. Таким чином: -

  • 'function-template': набір функцій, що описуються шаблоном, параметричні для певної інформації про тип, що надається як аргумент для цього шаблону. Наприклад :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
  • 'class-template': набір класів, описаних шаблоном, параметричний для певної інформації про тип, що надається як аргумент для цього шаблону. Наприклад :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
  • 'template-function': цей термін більше не дозволений. **
  • 'template-class': цей термін не дозволений. **

  • 'member-function-template': Цей термін не дозволений, оскільки він описує властивість, яка в даний час не підтримується визначенням шаблону. Використовуючи вищезазначену термінологічну конвенцію, це описує член некласного шаблону, визначення якого саме було шаблоном. Наприклад :-

class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};

Однак, оскільки шаблони в даний час обмежені глобальною сферою, такий шаблон є недійсним.

  • 'template-static-member-function':
  • 'шаблон-член-функція':
  • 'шаблон-статичний член':
  • 'template-static-data-member ' template-member ': Альтернативні терміни для визначення члена, що відображається окремо від' шаблону класу ', до якого він належить. Наприклад :-
template<class T> int S<T>::sep_member()
{ return i; }

Про Normalклас, який ви описали вище: я не знав, що такий шаблон-член-функція заборонений. Це прийнято всіма компіляторами, які я пробував. Чого мені не вистачає?
dan_din_pantelimon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.