16.10. Частичные специализации шаблонов классов A
16.10. Частичные специализации шаблонов классов A
Если у шаблона класса есть несколько параметров, то можно специализировать его только для одного или нескольких аргументов, оставляя другие неспециализированными. Иными словами, допустимо написать шаблон, соответствующий общему во всем, кроме тех параметров, вместо которых подставлены фактические типы или значения. Такой механизм носит название частичной специализации шаблона класса. Она может понадобиться при определении реализации, более подходящей для конкретного набора аргументов.
Рассмотрим шаблон класса Screen, введенный в разделе 16.2. Частичная специализации Screenhi,80 дает более эффективную реализацию для экранов с 80 столбцами:
template int hi, int wid
class Screen {
// ...
};
// частичная специализация шаблона класса Screen
template int hi
class Screenhi, 80 {
public:
Screen();
// ...
private:
string _screen;
string::size_type _cursor;
short _height;
// для экранов с 80 колонками используются специальные алгоритмы
};
Частичная специализация шаблона класса - это шаблон, и ее определение похоже на определение шаблона. Оно начинается с ключевого слова template, за которым следует список параметров, заключенный в угловые скобки. Список параметров здесь отличается от соответствующего списка параметров общего шаблона. Для частичной специализации шаблона Screen есть только один параметр-константа hi, поскольку значение второго аргумента равно 80, т.е. в данном списке представлены только те параметры, для которых фактические аргументы еще неизвестны.
Имя частичной специализации совпадает с именем того общего шаблона, которому она соответствует, в нашем случае Screen. Однако за ее именем всегда следует список аргументов. В примере выше этот список выглядит как . Поскольку значение аргумента для первого параметра шаблона неизвестно, то на этом месте в списке стоит имя параметра шаблона; вторым же аргументом является значение 80, которым частично специализирован шаблон.
Частичная специализация шаблона класса неявно конкретизируется при использовании в программе. В следующем примере частичная специализация конкретизируется аргументом шаблона 24 вместо hi:
Screen24,80 hp2621;
Обратите внимание, что экземпляр Screen24,80 может быть конкретизирован не только из частично специализированного, но и из общего шаблона. Почему же тогда компилятор остановился именно на частичной специализации? Если для шаблона класса объявлены частичные специализации, компилятор выбирает то определение, которое является наиболее специализированным для заданных аргументов. Если же ни одно из них не подходит, используется общее определение шаблона. Например, при конкретизации экземпляра Screen40,132 соответствующей аргументам шаблона специализации нет. Наш вариант применяется только для конкретизации типа Screen с 80 колонками.
Определение частичной специализации не связано с определением общего шаблона. У него может быть совершенно другой набор членов, а также собственные определения функций-членов, статических членов и вложенных типов. Содержащиеся в общем шаблоне определения членов никогда не употребляются для конкретизации членов его частичной специализации. Например, для частичной специализации Screen должен быть определен свой конструктор:
// конструктор для частичной специализации Screenhi,80
template int hi
Screenhi,80 ::Screen() : _height( hi ), _cursor( 0 ),
_screen( hi * 80, bk )
{ }
Если для конкретизации некоторого класса применяется частичная специализация, то определение конструктора из общего шаблона не используется даже тогда, когда определение конструктора Screen отсутствует.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Тела шаблонов
Тела шаблонов Шаблоны формируются по жестко заданным правилам. Они способны содержать элементы <xsl:param>, за которыми следует тело шаблона; в последнем могут содержаться данные PCDATA, инструкции XSLT, элементы расширения и элементы буквального
Рекурсивный вызов шаблонов
Рекурсивный вызов шаблонов Эта тема предназначена, главным образом, для программистов, поскольку здесь я буду пользоваться XSLT как языком программирования. В частности, я реализую вызов именованным шаблоном самого себя, то есть рекурсивный вызов. Классический пример
Создание шаблонов
Создание шаблонов При работе с корреспонденцией может возникнуть ситуация, когда в своих сообщениях вам придется неоднократно набирать повторяющийся текстовый фрагмент (простейший пример – приветствие и подпись). Согласитесь, в этом случае имеет смысл зафиксировать
Симуляция частичной специализации по виду аргумента шаблона
Симуляция частичной специализации по виду аргумента шаблона Использовать полученную метафункцию IsPointer‹T› для симуляции частичной специализации по виду аргумента шаблона можно примерно следующим образом:// Реализация общего случая: T не является указателем. template‹class
Использование шаблонов титров
Использование шаблонов титров Титры могут использоваться не только для показа на экране названия фильма и списка актеров. В немом кино с помощью титров выводились диалоги, в современных фильмах – место или время события в кадре, в информационных передачах – номера
Создание шаблонов
Создание шаблонов Если вам приходится много переписываться, очень скоро вы обнаружите, что вам надоело каждый раз писать «Доброе время суток!» в начале письма и «С искренними надеждами на плодотворное сотрудничество, Вассисуалий Апполинарович Иммануилов-Полесский» в
Создание шаблонов страниц
Создание шаблонов страниц Прежде всего, нам потребуется выбрать (указать) формат страницы, создать новый документ и хотя бы предварительно оформить мастер-страницы.Предположим, что наша книга будет формата 60 ? 90/16. Как мы знаем из первой части книги, без консультации в
16.1.1. Определения шаблонов классов Queue и QueueItem
16.1.1. Определения шаблонов классов Queue и QueueItem Ниже представлено определение шаблона класса Queue. Оно помещено в заголовочный файл Queue.h вместе с определением шаблона QueueItem:#ifndef QUEUE_H#define QUEUE_H// объявление QueueItemtemplate class T class QueueItem;template class Typeclass Queue {public:Queue() : front( 0 ), back ( 0 ) { }~Queue();Type&
16.3. Функции-члены шаблонов классов
16.3. Функции-члены шаблонов классов Как и для обычных классов, функция-член шаблона класса может быть определена либо внутри определения шаблона (и тогда называется встроенной), либо вне его. Мы уже встречались со встроенными функциями-членами при рассмотрении шаблона Queue.
16.6. Вложенные типы шаблонов классов
16.6. Вложенные типы шаблонов классов Шаблон класса QueueItem применяется только как вспомогательное средство для реализации Queue. Чтобы запретить любое другое использование, в шаблоне QueueItem имеется закрытый конструктор, позволяющий создавать объекты этого класса
16.9. Специализации шаблонов классов A
16.9. Специализации шаблонов классов A Прежде чем приступать к рассмотрению специализаций шаблонов классов и причин, по которым в них может возникнуть надобность, добавим в шаблон Queue функции-члены min() и max(). Они будут обходить все элементы очереди и искать среди них
Частичные функции
Частичные функции Спецификация всякого реалистичного примера, даже такого простого как стеки, неизбежно сталкивается с проблемами не всюду определенных операций: некоторые операции применимы не ко всем возможным элементам исходных множеств. Например, это имеет место
Парадокс расширения-специализации
Парадокс расширения-специализации Наследование иногда рассматривается как расширение, а иногда как специализация. Хотя эти два толкования как будто противоречат друг другу, оба они истинны - но с разных точек зрения.Все снова зависит от того, смотрим ли мы на класс как на
Отложенные классы как частичные интерпретации: классы поведения
Отложенные классы как частичные интерпретации: классы поведения Не все отложенные классы так близки к АТД как STACK. В промежутке между полностью абстрактным классом, таким как STACK, в котором все существенные компоненты отложены, и эффективным классом, таким как FIXED_STACK,