Урок №176. Параметр non-type в шаблоне

  Юрий  | 

  |

  Обновл. 15 Сен 2021  | 

 32062

 ǀ   8 

На предыдущих уроках мы узнали, как использовать параметр типа в шаблоне для создания функций и классов, которые не зависят от определенного типа данных. Однако параметр типа не является единственным параметром, который может иметь шаблон. Шаблоны классов и шаблоны функций могут иметь еще один параметр, известный как параметр non-type.

Параметр non-type

Параметр non-type в шаблоне — это специальный параметр шаблона, который заменяется не типом данных, а конкретным значением. Этим значением может быть:

   целочисленное значение или перечисление;

   указатель или ссылка на объект класса;

   указатель или ссылка на функцию;

   указатель или ссылка на метод класса;

   std::nullptr_t.

В следующем примере мы создадим шаблон класса StaticArray, который использует как параметр типа, так и параметр non-type. Параметр типа отвечает за тип данных элементов статического массива, а параметр non-type отвечает за размер выделяемого массива:

Результат выполнения программы:

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 в шаблоне класса!


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (168 оценок, среднее: 4,94 из 5)
Загрузка...

Комментариев: 8

  1. Евгений:

    Зачем в этом примере приведен метод getArray(), ведь он же совсем ничего не делает

    1. Алексей Л.:

      Для демонстрации того, как выглядит "Синтаксис определения шаблона метода и самого метода вне тела класса с параметром non-type".

  2. Kris:

    Правильно ли я понимаю, что non-type параметр мы должны знать во время компиляции? Т.е., он обязан быть константой, ведь, например, как в данном случае, мы выделяем на стеке массив размера size, и компилятор должен знать, на сколько передвинуть указатель стека, чтобы поместился этот объект еще до начала выполнения в асм коде? Или же, можно написать так:

    Если последний вариант, то размер стека определяется в runtime? Это было бы странно.

    1. Алексей Л.:

      Компилятор выдаст ошибку: non-type агрумент шаблона не является константным выражением.

  3. Dmitry:

    Возник вопрос. В данном примере не определен default constructor. А каким именно образом происходит (в какой последовательности) выделение памяти под массив?

    1. Александр:

      если default constructor класса не определен, то происходит просто последовательная инициализация "по умолчанию" для каждого поля класса. В том порядке, в котором они объявлены в описании класса

      1. Dred671:

        Наоборот вначале инициализируются поля, если конечно предоставлены значения, а уже потом в дело вступает конструктор и если его нет то будет предоставлен дефолтный который ничего не делает.

        1. Алексей Л.:

          Немного не так — при компиляции создается конструктор по умолчанию (если пользователь не задал свой). При создании объекта этот конструктор вызывается, выделяет память под объект, инициализирует поля класса, после этого выполняется "пустое" тело конструктора.

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *