С++ для начинающих




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


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

Встречаются ситуации, когда невозможно вывести аргументы шаблона в контексте, где конкретизируется шаблон функции; следовательно, необходимо их явно задать. Именно выявление таких ситуаций и необходимость решить проблему послужила причиной поддержки явного задания аргументов шаблона в стандартном C++.

В следующем примере берется адрес конкретизированной функции sum() и передается в качестве аргумента перегруженной функции manipulate(). Как мы показали в разделе 10.2, невозможно понять, как именно нужно конкретизировать sum(), если есть только списки параметров функций manipulate(). Имеется  две разных функции sum(), и обе удовлетворяют условиям вызова. Следовательно, вызов manipulate() неоднозначен. Одним из способов разрешения такой неоднозначности является явное приведение типов. Однако лучше использовать явное задание аргументов шаблона: оно позволяет указать, как именно конкретизировать sum(), и, следовательно, выбрать нужный вариант перегруженной функции manipulate(). Например:

template <class T1, class T2, class T3>

   T1 sum( T2 op1, T3 op2 ) { /* ... */ }

void manipulate( int (*pf)( int,char ) );

void manipulate( double (*pf)( float,float ) );

int main()

{

   // ошибка: какой из возможных экземпляров sum:

   // int sum( int,char ) или double sum( float, float )?

   manipulate( &sum );

   // берется адрес конкретизированного экземпляра

   // double sum( float, float )

   // вызывается: void manipulate( double (*pf)( float, float ) );

   manipulate( &sum< double, float, float > );

}

Отметим, что явное задание аргументов шаблона следует использовать только тогда, когда это абсолютно необходимо для разрешения неоднозначности или для конкретизации шаблона функции в контексте, где вывести аргументы невозможно. Во-первых, определение типов и значений аргументов шаблона проще оставить компилятору. А во-вторых, если мы модифицируем объявления в программе, так что типы аргументов функции при вызове конкретизированного шаблона изменятся, то компилятор автоматически скорректирует вызов без нашего вмешательства. С другой стороны, если аргументы шаблона заданы явно, необходимо проверить, что они по-прежнему отвечают новым типам аргументов функции. Поэтому мы рекомендуем избегать явного задания аргументов шаблона.

Упражнение 10.6

Назовите две ситуации, когда использование явного задания аргументов шаблона необходимо.

Упражнение 10.7

Пусть дано следующее определение шаблона функции sum():

template <class T1, class T2, class T3>

   T1 sum( T2, T3 );

Какие из приведенных ниже вызовов ошибочны? Почему?

double dobj1, dobj2;

float fobj1, fobj2;

char cobj1, cobj2;

(a) sum( dobj1, dobj2 );

(b) sum<double,double,double>( fobj1, fobj2 );

(c) sum<int>( cobj1, cobj2 );

(d) sum<double, ,double>( fobj2, dobj2 );




Содержание  Назад  Вперед