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




Разрешение перегрузки при конкретизации * - часть 7


3.      max(0,fd). Аргументы имеют тип int и float соответственно. Для вызова существует только один кандидат: обычная функция max(double, double). Вывод аргументов шаблона заканчивается неудачей, так как значения типа Type, выведенные из разных фактических аргументов функции, различны. Поэтому в множество кандидатов конкретизированная из шаблона функция не попадает. Обычная же функция устояла, поскольку существуют преобразования типов фактических аргументов в типы формальных параметров; она и выбирается. Если бы обычная функция не была объявлена, вызов закончился бы ошибкой.

А если бы мы определили еще одну обычную функцию для max()? Например:

template <class T> T max( T, T ) { ... }

// две обычные функции

char max( char, char );

double max( double, double );

Будет ли в таком случае третий вызов разрешен по-другому? Да.

int main() {

   float fd;

   // в пользу какой функции разрешается вызов?

   max( 0, fd );

}

Правило 3b говорит, что, поскольку вызов неоднозначен, следует рассматривать только обычные функции. Ни одна из них не считается наилучшей из устоявших, так как преобразования типов фактических аргументов одинаково плохи: в обоих случаях для установления соответствия требуется стандартная трансформация. Таким образом, вызов неоднозначен, и компилятор сообщает об ошибке.

Упражнение 10.11

Вернемся к представленному ранее примеру:

template <class Type>

   Type max( Type, Type ) { ... }

double max( double, double );

int main() {

   int ival;

   double dval;

   float fd;

   max( 0, ival );

   max( 0.25, dval );

   max( 0, fd );

}

Добавим в множество объявлений в глобальной области видимости следующую специализацию шаблона функции:

template <> char max<char>* char, char ) { ... }

Составьте список кандидатов и устоявших функций для каждого вызова max() внутри main().

Предположим, что в main() добавлен следующий вызов:

int main() {

   // ...

   max( 0, 'j' );

}

В пользу какой функции он будет разрешен? Почему?

Упражнение 10.12

Предположим, что есть следующее множество определений и специализаций шаблонов, а также объявления переменных и функций:

int i;             unsigned int ui;

char str[24];      int ia[24];

template <class T> T calc( T*, int );

template <class T> T calc( T, T );

template<> chat calc( char*. int );

double calc( double, double );

Выясните, какая функция или конкретизированный шаблон вызывается в каждом из показанных ниже случаев. Для каждого вызова перечислите функции-кандидаты и устоявшие функции; объясните, какая из устоявших функций будет наилучшей.

(a) cslc( str, 24 );        (d) calc( i, ui );

(b) calc( is, 24 );         (e) calc( ia, ui );

(c) calc( ia[0], 1 );       (f) calc( &i, i );




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