Частичная специализация шаблона


Частичная специализация шаблона — механизм языка программирования C++, предназначенный для специализации обобщённых шаблонных классов под конкретные задачи или под конкретное подмножество своих параметризованных типов данных. По мнению американского учёного и создателя C++ Б. Страуструпа специализация шаблонов является эффективным средством предотвращения неконтролируемого разрастания объёмов кода при активном использовании инструментария классов-шаблонов даже при разработке программных проектов умеренного размера. Это связывают с тем, что она не позволяет генерировать избыточные реплики кода под каждый конкретный тип данных, заменяя их более обобщёнными фрагментами кода и вдобавок сокращая время компиляции и компоновки конечного продукта.

Явная полная специализация

В C++ явная специализация параметризованного типа данных (шаблона) осуществляется через создание дополнительного класса-шаблона в котором входные параметры первичного класса полностью или частично переопределяются конкретными типами данных.

Синтаксис такого переопределения выглядит следующим образом:

template <список входных параметров класса-шаблона> class|struct|union имя_класса <список аргументов класса-шаблона>

Например:

// первичный класс template <typename Window, typename Controller> class Widget { /* ... реализация параметризованного класса Widget для любого вида окна Window и любого обработчика событий Controller */ }; // явная специализация первичного класса template <> class Widget <DialogWindow, DialogController> { /* ... реализация класса Widget под работу с диалоговым окном DialogWindow и обработчиком событий диалогового окна DialogController */ };

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

На этапе генерирования кода компилятор при поиске подходящего шаблона частично упорядочивает имеющиеся у него варианты специализации первичного класса и выбирает из них наиболее подходящий. Если таковой отсутствует, то компилятором генерируется сообщение об ошибке.

Частичная специализация

Частичная специализация шаблона класса определяется как некая конфигурация параметров первичного класса, которая служит аргументом специализированной реализации. Примером такой специализации может служить любой класс-контейнер, реализованный для хранения объектов-указателей:

// первичный класс template <typename T> class Vector { /* ... реализация класса-контейнера для объектов типа T... */ }; // частичная специализация первичного класса для хранения указателей template <typename T> class Vector<T*> { /* ... реализация класса-контейнера для указателей на объекты типа T... */ };

В этом случае аргумент-параметр шаблона не является выражением, переданным шаблону в качестве аргумента, а выводится из конструкции аргумента на базе объявленного шаблона первичного класса.

Частичная специализация отдельных методов параметризованного класса-шаблона не допускается, помимо этого для частичной специализации не предусмотрено использование параметров по умолчанию.

Пример

Гибкое использование частичной специализации шаблонов позволяет эффективно выполнять некоторые нетривиальные типы вычислений. Например, достаточно несложная композиция классов может помочь с вычислением структуры (количества размерностей) многомерного массива с элементами заранее неизвестного типа:

// первичный класс template<class T> struct RankOfArray { static const int value = 0; }; // рекуррентный частично специализированный класс template<class T, int N> struct RankOfArray < T[N] > { static const int value = 1+RankOfArray<T>::value; };

  • Apache Struts
  • PhpStorm
  • Транспайлер
  • Тер-Акопьян, Гурген Мкртычевич
  • Код с запашком

  •  

    • Яндекс.Метрика
    • Индекс цитирования