W poprzednich lekcjach nauczyłeś się używać parametrów typu szablonu do tworzenia funkcji i klas niezależnych od typu. Parametr typu szablonu jest typem zastępczym, który zastępuje typ przekazywany jako argument.
Parametry typu szablonu nie są jednak jedynym dostępnym typem parametrów szablonu. Klasy i funkcje szablonu mogą korzystać z innego rodzaju parametrów szablonu, znanego jako parametr inny niż typ.
Parametry inne niż typ
Parametr nietypowy szablonu to parametr szablonu, w którym typ parametru jest predefiniowany i zastępuje wartość constexpr przekazywaną jako argument.
Parametr inny niż typ może być dowolnego z następujących typów:
- Typ całkowity
- Wyliczenie typ
- Wskaźnik lub odwołanie do klasy obiekt
- Wskaźnik lub odwołanie do funkcji
- Wskaźnik lub odwołanie do funkcji składowej klasy
- std::nullptr_t
- Typ zmiennoprzecinkowy (od C++20)
W poniższym przykładzie tworzymy niedynamiczną (statyczną) klasę tablicową, która używa zarówno parametru typu, jak i parametru innego niż typ. Parametr type kontroluje typ danych tablicy statycznej, a całkowy parametr nietypowy kontroluje wielkość tablicy statycznej.
#include <iostream>
template <typename T, int size> // size to całkowy parametr nietypowy
class StaticArray
{
private:
// Parametr non-type kontrolowany rozmiar tablicy
T m_array[size] {};
public:
T* getArray();
T& operator[](int index)
{
return m_array[index];
}
};
// Pokazanie, jak funkcja dla klasy z parametrem innym niż typ jest zdefiniowana poza class
template <typename T, int size>
T* StaticArray<T, size>::getArray()
{
return m_array;
}
int main()
{
// zadeklaruj tablicę liczb całkowitych z miejscem na 12 liczb całkowitych
StaticArray<int, 12> intArray;
// Wypełnij w kolejności, a następnie wydrukuj wstecz
for (int count { 0 }; count < 12; ++count)
intArray[count] = count;
for (int count { 11 }; count >= 0; --count)
std::cout << intArray[count] << ' ';
std::cout << '\n';
// deklaracja podwójny bufor z miejscem na 4 doubles
StaticArray<double, 4> doubleArray;
for (int count { 0 }; count < 4; ++count)
doubleArray[count] = 4.4 + 0.1 * count;
for (int count { 0 }; count < 4; ++count)
std::cout << doubleArray[count] << ' ';
return 0;
}Kod ten generuje następujące informacje:
11 10 9 8 7 6 5 4 3 2 1 0 4.4 4.5 4.6 4.7
Wartą odnotowania rzeczą w powyższym przykładzie jest to, że nie musimy dynamicznie przydzielać zmiennej składowej m_array! Dzieje się tak, ponieważ dla dowolnej instancji klasy StaticArray rozmiar musi mieć wartość constexpr. Na przykład, jeśli utworzysz instancję StaticArray<int, 12>, kompilator zamieni size na 12. Zatem m_array jest typu int[12], który może być przydzielany statycznie.
Ta funkcjonalność jest używana przez standardową klasę biblioteczną std::array. Kiedy przydzielasz std::array<int, 5>, int jest parametrem typu, a 5 jest parametrem innym niż typ!
Zauważ, że jeśli spróbujesz utworzyć instancję szablonowego parametru innego typu z wartością inną niż constexpr, to nie zadziała:
template <int size>
class Foo
{
};
int main()
{
int x{ 4 }; // x nie jest constexpr
Foo<x> f; // błąd: argument nietypowy szablonu musi być constexpr
return 0;
}W takim przypadku kompilator zgłosi błąd.

