Симуляция частичной специализации

Симуляция частичной специализации

Авторы:

Жанр: Программирование

Циклы: не входит в цикл

Формат: Полный

Всего в книге 3 страницы. У нас нет данных о годе издания книги.

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

Читать онлайн Симуляция частичной специализации


Введение

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

>template‹class T, int Rows, int Columns›

>class Matrix {

> //…

>};

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

>template‹int Rows, int Columns›

>class Matrix‹float, Rows, Columns› {

> //…

>};

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

Техника симуляции

Естественным первым шагом будет вынести различающуюся функциональность Matrix‹› в два базовых класса: Matrix_‹›, реализующий общий случай, и Matrix_float_‹› для специфики Matrix‹float,…›.

>template‹class T, int Rows, int Columns›

>class Matrix_ {

> //…

>};


>template‹int Rows, int Columns› class Matrix_float_ {

> //…

>};

Таким образом, проблема сведется к тому, чтобы класс Matrix‹T, Rows, Columns› наследовался от Matrix_‹T, Rows, Columns› или Matrix_float_‹Rows, Columns›, в зависимости от того, является ли параметр T шаблона Matrix‹› типом float. Решение этой задачи и является главным «фокусом» данной техники.

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

>template‹class T›

>struct MatrixTraits {

> template‹int Rows, int Columns›

> struct Dimensions {

>  typedef Matrix_‹T, Rows, Columns› Base;

> };

>};


>template‹›

>struct MatrixTraits‹float› {

> template‹int Rows, int Columns›

> struct Dimensions {

>  typedef Matrix_float_‹Rows, Columns› Base;

> };

>};

Теперь осталось просто унаследовать Matrix‹› от соответствующего класса MatrixTraits‹›::…::Base.

>template‹class T, int Rows, int Columns›

>class Matrix: public MatrixTraits‹T›::template Dimensions‹Rows, Columns›::Base {

> //…

>};

ПРИМЕЧАНИЕ Согласно текущей версии стандарта, использование ключевого слова template при квалификации вложенного шаблона Dimensions в данном случае обязательно, хотя некоторые компиляторы и позволяют его опускать.

Использование

Метапрограммирование и метафункции

Прежде чем перейти к изложению дальнейшего материала, полезно ввести понятия метапрограммирования и метафункции. Если внимательнее посмотреть на то, что происходит, когда компилятор встречает пример, подобный наследованию класса Matrix от MatrixTraits‹T›::…::Base, можно заметить, что фактически это является программированием компилятора. То есть, в данном случае компилятор как бы получает инструкцию: «если тип шаблона является типом float, то считать базовым классом Matrix_float_‹›, в противном случае – Matrix_‹›. Это можно рассматривать как программирование вычислений времени компиляции. Подобные техники иногда называют метапрограммированием шаблонами или просто метапрограммированием, а шаблоны, подобные MatrixTraits, – метафункциями.

Частичная специализация по виду аргумента шаблона

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

>template‹class T›

>class С {

> //…

>};


>template‹class T›

>class С‹T*› {

> //…

>};

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

>template‹class T›

>struct IsPointer {

> static const bool value =…;

>};

где IsPointer‹T›::value принимает значения true или false в зависимости от того, является ли тип T указателем.

ПРИМЕЧАНИЕ Так как некоторые компиляторы не поддерживают должным образом определение статических констант времени компиляции в теле класса, эта метафункция может быть переписана эквивалентным образом с использованием enum.

Метафункция IsPointer‹T›

Задачу построения подобной метафункции решили в 2000 году сотрудники Adobe Systems Incorporated Мэт Маркус и Джесс Джонс. Суть решения сводится к использованию выражения вызова перегруженных функций внутри sizeof():

>// Типы TrueType и FalseType могут быть определены произвольным образом,

>// главное чтобы выполнялось условие: sizeof(TrueType)!= sizeof(FalseType).

>struct TrueType {char dummy_ [1];};

>struct FalseType {char dummy_ [100];};


>// Промежуточный класс PointerShim нужен,

>// чтобы избежать ошибочной работы метафункции

>// IsPointer в случае параметризации классом, в котором определен

>// оператор преобразования к указателю.

>struct PointerShim {

> PointerShim(const volatile void*);

>};

>// Т.к. функции ptr_discriminator на самом деле не вызываются, реализации не требуется.


С этой книгой читают
Обработка событий в С++

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


Экстремальное программирование. Разработка через тестирование
Автор: Кент Бек

Возвращение знаменитого бестселлера. Изящный, гибкий и понятный код, который легко модифицировать, который корректно работает и который не подкидывает своим создателям неприятных сюрпризов. Неужели подобное возможно? Чтобы достичь цели, попробуйте тестировать программу еще до того, как она написана. Именно такая парадоксальная идея положена в основу методики TDD (Test-Driven-Development – разработка, основанная на тестировании). Бессмыслица? Не спешите делать скороспелые выводы. Рассматривая применение TDD на примере разработки реального программного кода, автор демонстрирует простоту и мощь этой методики.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Перевод в электронный формат, кодированные наборы шрифтов и система Оптического Распознавания Символов для многошрифтовых информационных ресурсов на примере “Летописи журнальных статей”

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


Геймдизайн. Рецепты успеха лучших компьютерных игр от Super Mario и Doom до Assassin’s Creed и дальше

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.


Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Лобо

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


Тито

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


Фигурек
Автор: Фабрис Каро

Каждому приятно дружить со знаменитостью. Каждому (и каждой) лестно, если на его девушку (парня) на улице восхищенно оглядываются прохожие. Каждому хочется иметь настоящих друзей, с которыми можно делиться секретами и с увлечением отдаваться общему хобби. Короче говоря, всем нужны искренние привязанности и добрые отношения. Вот только где их взять? Автор «Фигурека» точно знает, где. И готов показать места.


Фукусима, или История собачьей дружбы

У Лабрадора Трисона появилось сразу двое подопечных – ветеран МЧС Владимир Петрович и немецкая овчарка Фукусима. Оба ослепли при сильном пожаре. С появлением Трисона их жизнь круто изменилась: Петрович начал выходить на улицу и наконец обрел свободу передвижения, а у Фукусимы появился настоящий друг. Благодаря преданности умного и сообразительного Лабрадора мужчина и собака смогли снова радоваться жизни. И все бы хорошо, но только Трисону периодически приходится защищаться от вредного кота Фараона, помогать Петровичу налаживать личную жизнь и защищать Фукусиму от насмешек других собак.


Поделиться мнением о книге