Шаблони (C++)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Шаблони (англ. template) — засіб мови C++, який призначений для кодування узагальнених алгоритмів, без прив'язки до деяких параметрів: типу даних, розміру буфера та стандартного значення. В C++ можливе створення шаблону функції і шаблону класу. Хоча шаблони надають коротку форму запису ділянки коду, насправді їх використання не скорочує виконаний код, тому що для кожного набору параметрів компілятор створює окремий екземпляр функції або класу.

Шаблонні функції[ред.ред. код]

При створенні функцій іноді виникають ситуації, коли дві функції виконують однакову послідовність дій, але працюють з різними типами даних (наприклад, одна використовує параметри типу int, а інша типу float або double). За допомогою механізму перевантаження функцій можна використовувати одне й те ж ім'я для функцій, що виконують різні дії і мають різні типи параметрів. Однак, якщо функції повертають значення різних типів, слід використовувати для них унікальні імена. Шаблонна функція дає можливість оперувати параметрами різних типів і повертати значення різних типів, що значно полегшує роботу і зменшує кількість змінних у коді. Іншими словами шаблонна функція являє собою набір функцій.

Наприклад, стандартна бібліотека C++ має шаблонну функцію max(x, y), яка повертає більше з двох значень (x або y). Функцію max() можна оголосити з використанням шаблонних типів, наступним чином:

template <typename Type>
Type max(Type a, Type b) {
    return a > b ? a : b;
}

Одна ця функція може працювати з різними типами даних. Хоча використання шаблонної функції економить кількість коду, в порівнянні з написанням множини окремих функцій для кожного типу параметрів, вона не зменшує об'єм скомпільованого коду. Наприклад, якщо в програмі функція використовується для двох ситуацій, де параметрами є значення типу int і double, компілятор скомпілює об'єктний код з версіями функції max(), одна з яких приймає параметри типу int, а друга double. Результат компіляції буде ідентичний тому, якби ми створили дві функції, замість використання шаблонної функції.

#include <iostream>
 
int main(int, char**)
{
  // Зробить виклик функції max <int> (за типом аргументів)
  std::cout << max(3, 7) << std::endl;
  // Зробить виклик функції  max<double> (за типом аргументів)
  std::cout << max(3.0, 7.0) << std::endl;
  // Ця ситуація є неоднозначною, тому слід явно вказати, що слід викликати max<double>
  std::cout << max<double>(3, 7.0) << std::endl;
  return 0;
}

Ініціалізація шаблонного класу[ред.ред. код]

Оголошення та визначення шаблону функції починається ключовим словом template, за яким слідує укладений в кутові дужки і розділений комами непорожній список параметрів шаблону. Ця частина оголошення або визначення зазвичай називається заголовком шаблону. Увага, не плутайте параметр шаблону і шаблон класу. Якщо нам треба створити шаблон класу, з одним параметром типу int або char, шаблон класу буде мати такий вигляд:

template <typename T>
class Name
{
// тіло шаблону класу
};

де T — це параметр шаблону класу, який може приймати будь-який з вбудованих типів даних, те, що нам і потрібно.

А якщо параметр шаблону класу повинен бути користувацького типу, наприклад типу Array, де Array — це клас, що описує масив, шаблон класу буде мати наступний вигляд:

template <class T>
class Name
{
// тіло шаблону класу
};

Параметри шаблонів[ред.ред. код]

Кожен параметр шаблону складається з службового слова class, за яким йде ідентифікатор. У контексті оголошення шаблону функції, службове слово class не несе ніякої особливого смислового навантаження. Справа в тому, що аналогічна конструкція використовується також і для оголошення шаблону класу, де ключове слово class грає свою особливу роль. У заголовку шаблону імена параметрів шаблону повинні бути унікальні. Параметрами шаблонів можуть бути: параметри-типи, параметри звичайних типів, параметри-шаблони. Для параметрів будь-якого типу можна вказувати значення за замовчуванням.

template <class T1, // параметр-тип
           typename T2, // параметр-тип
           int I, / / параметр звичайного типу
           T1 DefaultValue, // параметр звичайного типу
           template <class> class T3, // параметр-шаблон
           class Character = char> // параметр за замовчуванням
 

Шаблони як члени класів[ред.ред. код]

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

   class A
   {
   / * ... * /
   public:
     template <class T> T & ConvertTo ();
     template <class T> void ConvertFrom (const T & data);
   };
   template <class T>
   void f (T Container)
   {
     int i1 = Container.template ConvertTo <int> () + 1;
     Container.ConvertFrom (i1); // кваліфікатор не потрібен
   }

Див.також[ред.ред. код]