26.2 — Parametry nietypowe szablonu

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 is an integral non-type parameter
class StaticArray
{
private:
    // The non-type parameter controls the size of the array
    T m_array[size] {};

public:
    T* getArray();
	
    T& operator[](int index)
    {
        return m_array[index];
    }
};

// Showing how a function for a class with a non-type parameter is defined outside of the class
template <typename T, int size>
T* StaticArray<T, size>::getArray()
{
    return m_array;
}

int main()
{
    // declare an integer array with room for 12 integers
    StaticArray<int, 12> intArray;

    // Fill it up in order, then print it backwards
    for (int count { 0 }; count < 12; ++count)
        intArray[count] = count;

    for (int count { 11 }; count >= 0; --count)
        std::cout << intArray[count] << ' ';
    std::cout << '\n';

    // declare a double buffer with room for 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 is non-constexpr
    Foo<x> f; // error: the template non-type argument must be constexpr

    return 0;
}

W takim przypadku kompilator zgłosi błąd.

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
133 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze