Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
86
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

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

465

}

Функция ff(), принимающая два аргумента типа int, выбирается в качестве наилучшей из устоявших по следующим причинам:

1.ее первый аргумент лучше. 0 дает точное соответствие с формальным параметром типа int, тогда как для установления соответствия с параметром типа char * требуется стандартное преобразование указателя;

2.ее второй аргумент имеет тот же ранг. К аргументу 'a' типа char для установления

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

int compute( const int&, short ); int compute( int&, double );

extern int iobj; int main() {

compute( iobj, 'c' ); // compute( int&, double ) return 0;

Вот еще один пример:

}

Обе функции compute( const int&, short ) и compute( int&, double ) устояли.

Вторая выбирается в качестве наилучшей по следующим причинам:

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

2.ее второй аргумент имеет тот же ранг. К аргументу 'c' типа char для установления

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

9.4.4. Аргументы со значениями по умолчанию

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

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

466

extern void ff( int );

 

extern void ff( long, int = 0 );

 

int main() {

// соответствует ff( long, 0 );

 

ff( 2L );

 

ff( 0, 0 ); // соответствует ff( long, int ); ff( 0 ); // соответствует ff( int );

ff( 3.14 ); // ошибка: неоднозначность

}

Для первого и третьего вызовов функция ff() является устоявшей, хотя передан всего один фактический аргумент. Это обусловлено следующими причинами:

1.для второго формального параметра есть значение по умолчанию;

2.первый параметр типа long точно соответствует фактическому аргументу в первом вызове и может быть приведен к типу аргумента в третьем вызове за счет последовательности, имеющей ранг стандартного преобразования.

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

Упражнение 9.9

Объясните, что происходит при разрешении перегрузки для вызова функции compute() внутри main(). Какие функции являются кандидатами? Какие из них устоят после первого шага? Какие последовательности преобразований надо применить к фактическому аргументу, чтобы он соответствовал формальному параметру для каждой

namespace primerLib { void compute();

void compute( const void * );

}

using primerLib::compute; void compute( int );

void compute( double, double = 3.4 ); void compute( char*, char* = 0 );

int main() { compute( 0 ); return 0;

устоявшей функции? Какая функция будет наилучшей из устоявших?

}

Что будет, если using-объявление поместить внутрь main() перед вызовом compute()? Ответьте на те же вопросы.