Язык программирования C++. Вводный курс


Явное задание аргументов шаблона A - часть 2


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

// каким должен быть тип возвращаемого значения: T или U

template <class T, class U>

   ??? sum( T, U );

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

char ch; unsigned int ui;

 

// ни T, ни U нельзя использовать в качестве типа возвращаемого значения

sum( ch, ui );   // правильно: U sum( T, U );

sum( ui, ch );   // правильно: T sum( T, U );

Решение заключается в том, чтобы ввести в шаблон третий параметр для обозначения типа возвращаемого значения:

// T1 не появляется в списке параметров шаблона функции

template <class T1, class T2, class T3>

   T1 sum( T2, T3 );

Поскольку тип возвращаемого значения может отличаться от типов аргументов функции, T1 не упоминается в списке формальных параметров. Это потенциальная проблема, так как тип T1 не может быть выведен из фактических аргументов функции. Однако, если при конкретизации sum() мы зададим аргументы шаблона явно, то избегнем сообщения компилятора о невозможности вывести T1.

Например:

typedef unsigned int ui_type;

ui_type calc( char ch, ui_type ui ) {

 

   // ...

   // ошибка: невозможно вывести T1

   ui_type loc1 = sum( ch, ui );

 

   // правильно: аргументы шаблона заданы явно

   // T1 и T3 - это unsigned int, T2 - это char

   ui_type loc2 = sum< ui_type, ui_type >( ch, ui );

}

Не хватает возможности явно задать T1, но не  T2 и T3, поскольку их можно вывести из аргументов функции при вызове.

При явном задании аргументов шаблона необходимо перечислять только те, которые не могут быть выведены автоматически. Но, как и в случае аргументов функции со значениями по умолчанию, опускать можно исключительно “хвостовые”:

// правильно: T3 - это unsigned int

// T3 выведен из типа ui

ui_type loc3 = sum< ui_type, char >( ch, ui );

 

// правильно: T2 - это char, T3 - unsigned int

// T2 и T3 выведены из типа pf

ui_type (*pf)( char, ui_type ) = &sum< ui_type >;

 

// ошибка: опускать можно только “хвостовые” аргументы

<


Начало  Назад  Вперед