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




Конкретизация шаблона функции - часть 2


конкретизирует экземпляр min(), в котором Type заменено на double, а size на 6:

В качестве формальных параметров шаблона функции используются параметр-тип и параметр-константа. Для определения фактического типа и значения константы, которые надо подставить в шаблон, исследуются фактические аргументы, переданные при вызове функции. В нашем примере для идентификации аргументов шаблона при конкретизации используются тип ia (массив из пяти int) и da (массив из шести double). Процесс определения типов и значений аргументов шаблона по известным фактическим аргументам функции называется выведением (deduction) аргументов шаблона. (В следующем разделе мы расскажем об этом подробнее. А в разделе 10.4 речь пойдет о возможности явного задания аргументов.)

Шаблон конкретизируется либо при вызове, либо при взятии адреса функции. В следующем примере указатель pf инициализируется адресом конкретизированного экземпляра шаблона. Его аргументы определяются путем исследования типа параметра функции, на которую указывает pf:

template <typename Type, int size>

   Type min( Type (&p_array)[size] ) { /* ... */ }

// pf указывает на int min( int (&)[10] )

int (*pf)(int (&)[10]) = &min;

Тип pf – это указатель на функцию с параметром типа int(&)[10], который определяет тип аргумента шаблона Type и значение аргумента шаблона size при конкретизации min(). Аргумент шаблона Type будет иметь тип int, а значением аргумента шаблона size будет 10. Конкретизированная функция представляется как min(int(&)[10]), и указатель pf адресует именно ее.

Когда берется адрес шаблона функции, контекст должен быть таким, чтобы можно было однозначно определить типы и значения аргументов шаблона. Если сделать это не удается, компилятор выдает сообщение об ошибке:

template <typename Type, int size>

   Type min( Type (&r_array)[size] ) { /* ... */ }

typedef int (&rai)[10];

typedef double (&rad)[20];

void func( int (*)(rai) );

void func( double (*)(rad) );

int main() {

// ошибка: как конкретизировать min()?

   func( &min );

}

Функция func() перегружена и тип ее параметра не позволяет однозначно определить ни аргумент шаблона Type, ни значение аргумента шаблона size. Результатом конкретизации вызова func() может быть любая из следующих функций:

min( int (*)(int(&)[10]) )

min( double (*)(double(&)[20]) )

Поскольку однозначно определить аргументы функции func() нельзя, взятие адреса конкретизированного шаблона в таком контексте приводит к ошибке компиляции.

Этого можно избежать, если использовать явное приведение типов для указания типа аргумента:

int main() {

   // правильно: с помощью явного приведения указывается тип аргумента

   func( static_cast< double(*)(rad) >(&min) );

}

Лучше, однако, применять явное задание аргументов шаблона, как будет показано в разделе 10.4.




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