Zaochniki / 10_templ. Антон Гуда (CC BY-SA)
.pdf
Шаблоны классов
Синтаксис объявления
Создадим описание шаблонного класса (или шаблона класса Stack). Этот контейнер будет содержать объекты типа T.
template <typename |
T> |
|
|
||
c l a s s Stack { |
|
|
p u b l i c : |
|
|
Stack ( ) ; |
|
|
|
|
|
Stack ( const Stack<T> &r |
) ; |
|
~Stack ( ) ; |
|
|
void push ( const T& o b j ) ; |
||
T pop ( ) ; |
|
|
bool is_empty ( ) |
const { |
r e t u r n top == 0 } ; |
. . . |
|
|
|
|
|
} ; |
|
|
|
|
|
При написании функций-членов и функций-статических членов внутри шаблона не надо повторять ключевое слово typename.
Шаблоны
Определение функций шаблона класса вне его определения
При написании функций-членов и функций-статических членов снаружи шаблона надо использовать ключевое слово typename для указания того, что это не просто функция, а шаблон, зависящий от параметров.
template <typename T> Stack<T> :: Stack ( )
{ / тело конструктора / }
template <typename T> Stack<T>::~ Stack ( )
{ / тело деструктора / }
template <typename T>
void Stack<T> : : push ( const T& o b j ) { / тело функции push / }
Шаблоны
Дружественные функции шаблона класса
Если дружественная функция шаблона класса зависин от того же параметра, что и сам шаблон, то для е¼ описания и определения используется такой синтаксис:
template<typename |
T> |
i n t |
f f (T |
z ) ; |
// описание |
|
|
|||||||
|
|
|||||||||||||
template<typename |
T> c l a s s Tc { |
|
|
|
|
|
|
|
|
|||||
p r i v a t e : |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
i n t l ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
T x ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p u b l i c : |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tc (T xx ) : l ( 1 2 ) , x ( xx ) { } ; |
|
|
|
|
|
|
|
|
||||||
f r i e n d i n t |
f f <>(T |
z ) ; |
// пустые |
скобки <> |
|
|
||||||||
// обозначают , что |
f f |
зависит |
îò |
òîãî æå |
параметра |
|
||||||||
} ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename |
T> |
i n t |
f f (T |
z ) { |
r e t ur n |
z >l ; } ; |
||||||||
// определение |
шаблона |
дружественной функции шаблона |
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Шаблоны
Инстанцирование шаблонов класса
В отличие от функций, инстанцирование шаблонов классов происходит только явно:
i n t main ( ) |
|
|
|
|
|
|
|
|
|
|
|
||
{ |
|
|
|
|
|
|
Stack<in t > |
s i ; // |
точка инстанцирования |
||||
|
|
// Stack<T> äëÿ |
i n t |
|||
Stack<double> sd ; |
// |
. . . |
äëÿ |
d o u b l e |
||
Stack<Stud> |
s s t d ; |
// |
. . . |
äëÿ |
Stud |
|
Stack<Stack< int > > xx ; // . . . |
äëÿ Stack<i n t > |
|||||
s i . push ( 5 4 ) ; sd . push ( 0 . 5 ) ; |
|
|||||
s s t d . push ( |
Stud ( " Katya " , 17 ) |
) ; |
||||
cout << |
s i . pop ( ) << ' |
' << sd . pop << e n d l ; |
||||
|
|
|
|
|
|
|
r e t u r n |
0 ; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Инстанцирование происходит только для тех типов, и для тех функций, которые используются.
Шаблоны
Специализация шаблонов класса
Если для какого-то типа T надо задать другое поведение, то можно использовать специализацию шаблона.
template<>
c l a s s Stack<i nt > {
. . . |
|
} ; // |
полная специализация класса Stack |
// |
для случая , если T i n t |
Для полных специализаций функии-члены пишутся как обычные функции-члены, заменяя T на тип специализации.
void Stack<in t > :: push ( i n t& o b j )
{
. . .
}
Шаблоны
Частичная (неполная) специализация
Если у шаблона класса несколько параметров, или необходимо использовать неполную специализацию
template<typename |
T> |
|
|
||||
|
|
||||||
c l a s s Stack<T > { |
|
|
|
|
|||
. . . |
|
|
|
|
|
|
|
} ; // |
неполная |
специализация класса Stack |
|||||
// |
для случая , |
åñëè |
параметр указатель |
||||
i n t main ( ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Stack<in t > |
a ; |
// |
используется полная спец . |
||||
Stack<i n t > |
xa ; |
// . . . |
частичная |
||||
Stack<Stud > |
spa ; |
// |
. . частичная |
||||
Stack<Stud> z ; |
// |
общий |
случай |
||||
r e t u r n 0 ; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Если одинакого хорошо подходят две неполные специализацииошибка. 





Шаблоны
Аргументы по умолчанию для шаблонов
Несколько последних параметров шаблонов могут иметь значение по умолчанию.
template< typename T, typename L = i n t > c l a s s V e c t o r {
.. .
};
i n t main ( )
{
Vector <double> a ; // используется
// Vector <double , i n t >
Vector <i nt , long> z ; // задано явно r e t u r n 0 ;
}
Шаблоны
STL
Занчительная часть стандартной библиотеки языка C++ STL (Standard Template Library) основана на шаблонах. Это используется как явно,
v e c t o r <i nt > a ; map<double , in t > mp ;
так и неявно:
s t r i n g s ;
// на самом деле ' s t r i n g ' может быть определ¼н так : typedef b a s i c _ s t r i n g <char , c h a r _ t r a i t s <char >,
A l l o c a t o r <char> > s t r i n g ;
Шаблоны
