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




Разрешение имен в определениях шаблонов * - часть 2


print( "Minimum value found: ");

не зависит от параметров шаблона, то функция print() для печати строк символов должна быть объявлена до использования. Чтобы исправить эту ошибку, можно поместить объявление print() перед определением min():

// ---- primer.h ----

// это объявление необходимо:

// внутри min() вызывается print( const char * )

void print( const char * );

template <typename Type>

   Type min( Type* array, int size ) {

   // ...

   print( "Minimum value found: ");

   print( min_val );

   return min_val;

}

С другой стороны, объявление функции print(), используемой для печати min_val, пока не нужно, так как еще неизвестно, какую конкретно функцию надо искать. Мы не знаем, какая функция print() будет вызвана при обращении print(min_val), пока тип min_val не станет известным.

Когда же должна быть объявлена функция print(), вызываемая при обращении print(min_val)? До конкретизации шаблона. Например:

#include <primer.h>

void print( int );

int ai[4] = {12, 8, 73, 45 };

int main() {

   int size = sizeof(ai) / sizeof(int);

   // конкретизируется min( int*, int )

   min( &ai[0], size );

}

main() вызывает конкретизированную из шаблона функцию min(int*,int). В этой реализации Type заменено int, и тип переменной min_val, следовательно, равен int. Поэтому при обращении print(min_val) вызывается функция с аргументом типа int. Именно тогда, когда конкретизируется min(int*,int), становится известно, что при втором вызове аргумент print() имеет тип int. В этот момент такая функция должна быть видима. Если бы функция print(int) не была объявлена до конкретизации min(int*,int), то компилятор выдал бы сообщение об ошибке.

Поэтому разрешение имен в определении шаблона происходит в два этапа. Сначала разрешаются имена, не зависящие от его параметров, а затем, при конкретизации, – имена, зависящие от параметров.

Но зачем нужны два шага? Почему бы, например, не разрешать все имена при конкретизации?




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