На попередніх уроках ми дізналися, як використовувати параметр типу в шаблоні для створення функцій і класів, які не залежать від певного типу даних. Однак параметр типу не є єдиним параметром, який може мати шаблон. Шаблони класів і шаблони функцій можуть мати ще один параметр, відомий як параметр non-type.
Параметр non-type
Параметр non-type в шаблоні — це спеціальний параметр шаблону, який замінюється не типом даних, а конкретним значенням. Цим значенням може бути:
цілочисельне значення або перерахування;
вказівник або посилання на об’єкт класу;
вказівник або посилання на функцію;
вказівник або посилання на метод класу;
У наступному прикладі ми створимо шаблон класу StaticArray, який використовує як параметр типу, так і параметр non-type. Параметр типу відповідає за тип даних елементів статичного масиву, а параметр non-type відповідає за розмір виділеного масиву:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <iostream> template <class T, int size> // size є параметром non-type в шаблоні класу class StaticArray { private: // Параметр non-type в шаблоні класу відповідає за розмір виділеного масиву T m_array[size]; public: T* getArray(); T& operator[](int index) { return m_array[index]; } }; // Синтаксис визначення шаблону методу і самого методу поза тілом класу з параметром non-type template <class T, int size> T* StaticArray<T, size>::getArray() { return m_array; } int main() { // Оголошуємо цілочисельний масив з 10 елементів StaticArray<int, 10> intArray; // Заповнюємо масив значеннями for (int count=0; count < 10; ++count) intArray[count] = count; // Виводимо елементи масиву у зворотному порядку for (int count=9; count >= 0; --count) std::cout << intArray[count] << " "; std::cout << '\n'; // Оголошуємо масив типу double з 5 елементів StaticArray<double, 5> doubleArray; // Заповнюємо масив значеннями for (int count=0; count < 5; ++count) doubleArray[count] = 5.5 + 0.1*count; // Виводимо елементи масиву for (int count=0; count < 5; ++count) std::cout << doubleArray[count] << ' '; return 0; } |
Результат виконання програми:
9 8 7 6 5 4 3 2 1 0
5.5 5.6 5.7 5.8 5.9
Нам навіть не довелося динамічно виділяти змінну-член m_array! Це пов’язано з тим, що для будь-якого створеного об’єкта класу StaticArray його розмір є конкретно заданим значенням (можна сказати константою), яке передає користувач. Наприклад, якщо ми створимо екземпляр StaticArray<int, 10>, то компілятор замінить змінну розміру масиву (size) на 10. Таким чином, ми отримаємо m_array типу int[10], який можна виділити статичним чином.
Цю особливість використовує вже відомий нам клас зі Стандартної бібліотеки С++ — std::array. Коли ми виділяємо std::array<int, 5>, то int є параметром типу, а 5 — параметром non-type в шаблоні класу!
