template <unsigned int size> Buf{ ... };
Buf< 1024 > bpObj; // преобразование из int в unsigned int
(Более подробно они описаны в разделе 9.3.)
Рассмотрим следующие объявления:
extern void foo( char * );
extern void bar( void * );
typedef void (*PFV)( void * );
const unsigned int x = 1024;
template <class Type,
unsigned int size,
PFV handler> class Array { ... };
Array<int, 1024U, bar> a0; // правильно: преобразование не нужно
Array<int, 1024U, foo> a1; // ошибка: foo != PFV
Array<int, 1024, bar> a2; // правильно: 1024 преобразуется в unsigned int
Array<int, 1024, bar> a3; // ошибка: foo != PFV
Array<int, x, bar> a4; // правильно: преобразование не нужно
Array<int, x, foo> a5; // ошибка: foo != PFV
Объекты a0 и a4 класса Array определены правильно, так как аргументы шаблона точно соответствуют типам параметров. Объект a2 также определен правильно, потому что аргумент 1024 типа int приводится к типу unsigned int параметра-константы size с помощью преобразования целых типов. Объявления a1, a3 и a5 ошибочны, так как не существует преобразования между любыми двумя типами функций.
Приведение значения 0 целого типа к типу указателя недопустимо:
template <int *ptr>
class BufPtr { ... };
// ошибка: 0 имеет тип int
// неявное преобразование в нулевой указатель не применяется
BufPtr< 0 > nil;
Упражнение 16.3
Укажите, какие из данных конкретизированных шаблонов действительно приводят к конкретизации:
template < class Type >
class Stack { };
void f1( Stack< char > ); // (a)
class Exercise {
// ...
Stack< double > &rsd; // (b)
Stack< int > si; // (c)
};
int main() {
Stack< char > *sc; // (d)
f1( *sc ); // (e)
int iObj = sizeof( Stack< string > ); // (f)
}
Упражнение 16.4
Какие из следующих конкретизаций шаблонов корректны? Почему?
template < int *ptr > class Ptr ( ... };
template < class Type, int size > class Fixed_Array { ... };
template < int hi, int wid > class Screen { ... };
(a) const int size = 1024;
Ptr< &size > bp1;
(b) int arr[10];
Ptr< arr > bp2;
(c) Ptr < 0 > bp3;
(d) const int hi = 40;
const int wi = 80;
Screen< hi, wi+32 > sObj;
(e) const int size_val = 1024;
Fixed_Array< string, size_val > fa1;
(f) unsigned int fasize = 255;
Fixed_Array< int, fasize > fa2;
(g) const double db = 3.1415;
Fixed_Array< double, db > fa3;