Buf< c_size_val > buf1; // правильно
Buf< sizeof(size_val) > buf2; // правильно: sizeof(int)
BufPtr< &size_val > bp0; // правильно
// ошибка: нельзя вычислить во время компиляции
Buf< size_val > buf3;
Вот еще один пример, иллюстрирующий использование параметра-константы для представления константного значения в определении шаблона, а также применение его аргумента для задания значения этого параметра:
template < class Type, int size >
class FixedArray {
public:
FixedArray( Type *ar ) : count( size )
{
for ( int ix = 0; ix < size; ++ix )
array[ ix ] = ar[ ix ];
}
private:
Type array[ size ];
int count;
};
int ia[4] = { 0, 1, 2, 3 };
FixedArray< int, sizeof( is ) / sizeof( int ) > iA{ ia );
Выражения с одинаковыми значениями считаются эквивалентными аргументами для параметров-констант шаблона. Так, все три экземпляра Screen ссылаются на один и тот же конкретизированный из шаблона класс Screen<24,80>:
const int width = 24;
const int height = 80;
// все это Screen< 24, 80 >
Screen< 2*12, 40*2 > scr0;
Screen< 6+6+6+6, 20*2 + 40 > scr1;
Screen< width, height > scr2;
Между типом аргумента шаблона и типом параметра-константы допустимы некоторые преобразования. Их множество является подмножеством преобразований, допустимых для аргументов функции:
template <int *ptr> class BufPtr { ... };
int array[10];
BufPtr< array > bpObj; // преобразование массива в указатель
template <const int *ptr> class Ptr { ... };
int iObj;
Ptr< &iObj > pObj; // преобразование из int* в const int*
template <int hi, int wid> class Screen { ... };
const short shi = 40;
const short swi = 132;
Screen< shi, swi > bpObj2; // расширения типа short до int