#include
using namespace std;
2 :
template ctypename T>
class TestStatic
{
public:
static int StaticValue;
8: };
9
:о // инициализация статического члена
template int TestStatic::StaticValue;
12
:з int main ()
{
TestStatic Int_Year;
cout « "Setting StaticValue for Int_Year to 2011" « endl;
Int_Year.StaticValue = 2011;
TestStatic Int_2;
:о TestStatic Double_l;
: i TestStatic Double_2;
cout « "Setting StaticValue for Double_2 to 1011" « endl;
Double_2.StaticValue = 1011;
24
25
|
cout
|
«
|
"Int_2.StaticValue = " «
|
Int_2.StaticValue « endl;
|
26
|
cout
|
«
|
"Double_l.StaticValue =
|
" « Double_l.StaticValue
|
27
|
|
«
|
endl;
|
|
|
|
|
|
return 0;
}
Результат
Setting StaticValue for Int_Year to 2011
Setting StaticValue for Double_2 to 1011
Int_2.StaticValue = 2011
Double_l.StaticValue = 1011
Анализ
В строках 17 и 21 устанавливаю тся значения члена S t a t i c V a l u e экземпляров ш а блона для типов i n t и d o u b le соответственно. В строках 25 и 26 функции m a in () это значение читается с использованием членов других экземпляров — I n t _ 2 и D o u b le l .
Вывод демонстрирует, что были получены два разных значения S t a t i c V a l u e — 2011 установлено с использованием другого экземпляра, специализированного для типа i n t ,
значение 1011 установлено с использованием другого экземпляра, специализированного для типа d o u b le .
Таким образом, компилятор гарантировал неизменность поведения статической пере менной при специализации класса для типа. Каждая специализация шаблона класса фак тически получает собственную статическую переменную.
ПРИМЕЧАНИЕ
Обратите внимание на синтаксис создания экземпляра статического члена для
шаблона класса в строке 11 листинга 14.5.
template int TestStatic::StaticValue;
Он имеет такой формат:
tem piate< параметры шаблона>
СтатическийТип МмяКласса<Аргументы
Шаблона>::ИмяСтатическойПеременной;
370 ЗАНЯТИЕ 14. Макросы и шаблоны
С-и-11___________________________________
Использование макроса static_assert для проверки во время компиляции
Язык C++11 допускает блочную компиляцию, если определенные проверки не выпол няются. Звучит фантастически, но может оказаться весьма полезным с шаблонами клас сов. Вы могли бы, например, захотеть гарантировать, что экземпляр вашего шаблона клас са не будет создан для типа in t ! М акрос s t a t i c _ a s s e r t позволяет отобразить во время компиляции специальное сообщение в вашей среде разработки (или на консоли):
static_assert(проверяемое выражение, " Сообщение об ошибке, когда проверка терпит неудачу") ;
Чтобы предотвратить создание экземпляра вашего шаблона класса для типа i n t , мож
но использовать макрос s t a t i c _ a s s e r t () с оператором s i z e o f (Т ), сравнивая его ре зультат с результатом оператора s i z e o f ( i n t ) и отображая сообщение об ошибке, если проверка неравенства терпит неудачу:
static_assert(sizeof(Т)
!= sizeof (int),
"No int please!");
Такой шаблон класса, использующий макрос s t a t i c _ a s s e r t для блокирования компи ляции при создании экземпляров для определенных типов, представлен в листинге 14.6.
ЛИСТИНГ 14.6. Привередливый шаблон класса, возражающий
против создания экземпляра для типа int___________________________________________
О: template
class EverythingButlnt
2 : {
public:
EverythingButlnt()
{
static_assert(sizeof(T) != sizeof(int), "No int please!");
}
};
9:
10: int main()
11: {
EverythingButInt test; // создание экземпляра шаблона
для типа int.
return 0;
}
Результат
Никакого вывода нет, при ошибке компиляции отображается заданное вами сообщение:
error: No int please!
Анализ
Возражение, заданное в строке 6, регистрируется компилятором. Таким образом, ма крос s t a t i c _ a s s e r t — это способ, предоставляемый языком С++11 для защиты вашего кода шаблона от нежелательного создания экземпляра.
Использование шаблонов в практическом программировании на C++
Самое важное и мощное применение шаблоны нашли в ст андарт ной библиотеке ш а блонов (Standard Template Library — STL). Библиотека STL состоит из коллекции шабло нов классов и функций, содержащей обобщенные вспомогательные классы и алгоритмы. Эти шаблоны классов библиотеки STL позволяют реализовать динамические массивы, списки и контейнеры пар “ключ-значение”, в то время как алгоритмы, такие как сортиров ка, работают с этими контейнерами и обрабатывают данные, которые они содержат.
Знание синтаксиса шаблонов, который вы изучили здесь, очень поможет в использова нии контейнеров и функций STL, подробности которых рассматриваются на следующих занятиях. Хорошее понимание контейнеров и алгоритмов библиотеки STL, в свою очередь, поможет вам создавать эффективные приложения C++ с использованием проверенной и надежной реализации библиотеки STL, а также избежать долгих часов разбирательства в деталях шаблонов.
РЕКОМЕНДУЕТСЯ
Используйте шаблоны для реализации обоб щенных концепций
Предпочитайте шаблоны макросам
Do'stlaringiz bilan baham: |