» » » Павел Кузнецов - Симуляция частичной специализации


Авторские права

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

Здесь можно скачать бесплатно "Павел Кузнецов - Симуляция частичной специализации" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование, издательство RSDN Group. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Павел Кузнецов - Симуляция частичной специализации
Рейтинг:
Название:
Симуляция частичной специализации
Издательство:
RSDN Group
Год:
неизвестен
ISBN:
нет данных
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

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

Описание и краткое содержание "Симуляция частичной специализации" читать бесплатно онлайн.








Павел Кузнецов

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

Введение

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

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 на самом деле не вызываются, реализации не требуется.

TrueType ptr_discriminator(PointerShim);

FalseType ptr_discriminator(…);


// IsPointer‹T›::value == true, если T является указателем,

// IsPointer‹T›::value == false в противном случае.

template‹class T›

class IsPointer {

private:

 static T t_;

public:

 enum {

 value = sizeof(ptr_discriminator(t_)) == sizeof(TrueType)};

};


// Так как объект типа void создан быть не может,

// случай IsPointer‹void› должен обрабатываться отдельно.

template‹›

class IsPointer‹void› {

public:

 enum {value = false};

};

ПРЕДУПРЕЖДЕНИЕ Строго говоря, необходимо предоставлять не только специализацию для void, но и для соответствующих cv-квалифицированных разновидностей: const void, volatile void, const volatile void. Эти специализации опущены для краткости изложения.

ПРИМЕЧАНИЕ Функции, подобные ptr_discriminator, иногда называют дискриминирующими.

Техника основана на том, что во время компиляции выражения sizeof(ptr_discriminator(t_)) компилятор вынужден выбрать из двух перегруженных функций ptr_discriminator наиболее подходящую. В случае, если IsPointer‹T›::t_ является указателем, будет выбрана функция ptr_discriminator(PointerShim), возвращающая значение типа TrueType, и значение IsPointer‹T›::value обращается в true, т.к. sizeof(ptr_discriminator(PointerShim)) – sizeof(TrueType); в противном случае подходящей является функция ptr_discriminator(…)и значением IsPointer‹T›::value является false, т.к. sizeof(ptr_discriminator(…)) – sizeof(FalseType), а типы TrueType и FalseType выбраны таким образом, что sizeof(TrueType)!= sizeof(FalseType).

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

TrueType simple_ptr_discriminator(const volatile void*);

FalseType simple_ptr_discriminator(…);

Однако, в этом случае, метафункция IsPointer будет работать неверно, например, для таких классов:

struct C {

 operator int*() const {return 0;}

};

Так как класс C имеет операцию приведения к указателю, функция simple_ptr_discriminator может быть вызвана с любым объектом этого класса, и, следовательно, метафункция, построенная с использованием simple_ptr_discriminator, будет ошибочно определять подобные классы как указатели.

Пример. Для пущей ясности можно рассмотреть, как работает метафункция IsPointer‹T› на примере типа int. IsPointer‹int› разворачивается компилятором примерно в следующее:

// псевдокод

class IsPointer‹int› {

private:

 static int t_;

public:

 enum {value = sizeof(ptr_discriminator(t_)) == sizeof(TrueType)};

};

ptr_discriminator(PointerShim) для t_ не подходит, т.к. объект PointerShim может быть создан только из указателя. Следовательно, подходящей будет оставшаяся ptr_discriminator(…), которая возвращает FalseType. Значит, в данном случае выражение sizeof(ptr_discriminator(t_)) эквивалентно выражению sizeof(FalseType), значение которого по условию не равно sizeof(TrueType). Следовательно, IsPointer‹int›::value == false.


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Симуляция частичной специализации"

Книги похожие на "Симуляция частичной специализации" читать онлайн или скачать бесплатно полные версии.


Понравилась книга? Оставьте Ваш комментарий, поделитесь впечатлениями или расскажите друзьям

Все книги автора Павел Кузнецов

Павел Кузнецов - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

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

Отзывы о "Павел Кузнецов - Симуляция частичной специализации"

Отзывы читателей о книге "Симуляция частичной специализации", комментарии и мнения людей о произведении.

А что Вы думаете о книге? Оставьте Ваш отзыв.