Частичная специализация шаблона — механизм языка программирования C++, предназначенный для специализации обобщённых шаблонных классов под конкретные задачи или под конкретное подмножество своих параметризованных типов данных[1]. По мнению американского учёного и создателя C++ Б. Страуструпа специализация шаблонов является эффективным средством предотвращения неконтролируемого разрастания объёмов кода при активном использовании инструментария классов-шаблонов даже при разработке программных проектов умеренного размера. Это связывают с тем, что она не позволяет генерировать избыточные реплики кода под каждый конкретный тип данных, заменяя их более обобщёнными фрагментами кода и вдобавок сокращая время компиляции и компоновки конечного продукта[2].
В C++ явная специализация параметризованного типа данных (шаблона) осуществляется через создание дополнительного класса-шаблона в котором входные параметры первичного класса полностью или частично переопределяются конкретными типами данных[1][3].
Синтаксис такого переопределения выглядит следующим образом[4]:
// первичный классtemplate<typenameWindow,typenameController>classWidget{/* ... реализация параметризованного класса Widget для любого вида окна Window и любого обработчика событий Controller */};// явная специализация первичного классаtemplate<>classWidget<DialogWindow,DialogController>{/* ... реализация класса Widget под работу с диалоговым окном DialogWindow и обработчиком событий диалогового окна DialogController */};
Отмечается, что определения типов данных, содержащиеся в первичном классе, никогда не используются для конкретизации членов его частичной специализации. Однако, кодовая имплементация специализированных версий первичного класса никак с ним не связана и может содержать в себе набор членов, которые не имеют ничего общего с членами первичного класса[4].
На этапе генерирования кода компилятор при поиске подходящего шаблона частично упорядочивает имеющиеся у него варианты специализации первичного класса и выбирает из них наиболее подходящий. Если таковой отсутствует, то компилятором генерируется сообщение об ошибке[4].
Частичная специализация
Частичная специализация шаблона класса определяется как некая конфигурация параметров первичного класса, которая служит аргументом специализированной реализации. Примером такой специализации может служить любой класс-контейнер, реализованный для хранения объектов-указателей[2][5]:
// первичный классtemplate<typenameT>classVector{/* ... реализация класса-контейнера для объектов типа T... */};// частичная специализация первичного класса для хранения указателейtemplate<typenameT>classVector<T*>{/* ... реализация класса-контейнера для указателей на объекты типа T... */};
В этом случае аргумент-параметр шаблона не является выражением, переданным шаблону в качестве аргумента, а выводится из конструкции аргумента на базе объявленного шаблона первичного класса[2].
Частичная специализация отдельных методов параметризованного класса-шаблона не допускается[1], помимо этого для частичной специализации не предусмотрено использование параметров по умолчанию[5].
Пример
Гибкое использование частичной специализации шаблонов позволяет эффективно выполнять некоторые нетривиальные типы вычислений. Например, достаточно несложная композиция классов может помочь с вычислением структуры (количества размерностей) многомерного массива с элементами заранее неизвестного типа[5]:
// первичный классtemplate<classT>structRankOfArray{staticconstintvalue=0;};// рекуррентный частично специализированный классtemplate<classT,intN>structRankOfArray<T[N]>{staticconstintvalue=1+RankOfArray<T>::value;};
↑Baumann R.3.1 Explicit specialization // A profound reflection on C++ template mechanism. — Zurich: Swiss Federal Institute of Technology ETH, 2002. — P. 10.
↑ 123Побегайло А. П.19.5 Частичная специализация шаблона класса // C/C++ для студентов. — БХВ-Петербург, 2006. — С. 265. — 528 с. — (Computers). — ISBN 5-94157-647-1.
↑ 123Baumann R.3.2 Partial specialization of class template // A profound reflection on C++ template mechanism. — Zurich: Swiss Federal Institute of Technology ETH, 2002. — P. 13.