Сопоставление аргументов
Перегруженные функции выбираются для оптимального соответствия объявлений функций в текущей области аргументам, предоставленным в вызове функции. Если подходящая функция найдена, эта функция вызывается. "Подходящая" в данном контексте означает одно из следующего.
Точное соответствие найдено.
Тривиальное преобразование выполнено.
Восходящее приведение целого типа выполнено.
Стандартное преобразование в требуемый тип аргумента существует.
Пользовательское преобразование (оператор преобразования или конструктор) в требуемый тип аргумента существует.
Аргументы, представленные многоточием, найдены.
Компилятор создает набор функций-кандидатов для каждого аргумента. Функции-кандидаты — это функции, в которых фактический аргумент в данной позиции можно преобразовать в тип формального аргумента.
Для каждого аргумента создается набор наиболее подходящих функций, и выбранная функция представляет собой пересечение всех наборов. Если на пересечении находится несколько функций, перегрузка является неоднозначной и выдает ошибку. Функция, которая выбирается в конечном итоге, всегда является самой подходящей по сравнению с остальными функциями в группе по крайней мере для одного аргумента. В противном случае (если невозможно определить наиболее подходящую функцию) при вызове функции выдается ошибка.
Рассмотрим следующие объявления (функции отмечены как Variant 1, Variant 2 и Variant 3 для ссылки в последующем обсуждении).
Fraction &Add( Fraction &f, long l ); // Variant 1
Fraction &Add( long l, Fraction &f ); // Variant 2
Fraction &Add( Fraction &f, Fraction &f ); // Variant 3
Fraction F1, F2;
Рассмотрим следующий оператор.
F1 = Add( F2, 23 );
Представленный выше оператор создает два набора.
Набор 1. Функции-кандидаты, имеющие первый аргумент дробного типа |
Набор 2. Функции-кандидаты, второй аргумент которых можно преобразовать в тип int |
---|---|
Variant 1 |
Variant 1 (int можно преобразовать в long с помощью стандартного преобразования) |
Variant 3 |
|
Функции в наборе 2 представляют собой функции, для которых выполнены неявные преобразования из типа фактического параметра в тип формального параметра. Среди таких функций имеется функция, для которой затраты преобразования из типа фактического параметра в тип формального параметра являются наименьшими.
Пересечением этих двух наборов является функция Variant 1. Ниже представлен пример неоднозначного вызова функции.
F1 = Add( 3, 6 );
В предыдущем вызове функции создаются следующие наборы.
Набор 1. Функции-кандидаты, имеющие первый аргумент типа int |
Набор 2. Функции-кандидаты, имеющие второй аргумент типа int |
---|---|
Variant 2 (int можно преобразовать в long с помощью стандартного преобразования) |
Variant 1 (int можно преобразовать в long с помощью стандартного преобразования) |
Обратите внимание, что на пересечении этих наборов функция отсутствует. Поэтому компилятор создает сообщение об ошибке.
Для сопоставления аргументов функция с аргументами по умолчанию n обрабатывается как отдельные функции n+1, при этом каждая функция имеет разное количество аргументов.
Многоточие (...) выступает в качестве подстановочного знака; оно соответствует любому фактическому аргументу. Это может привести к появлению множества неоднозначных наборов, если не соблюдать предельную осторожность при разработке наборов перегруженных функций.
Примечание
Неоднозначность перегруженных функций невозможно определить, пока не будет обнаружен вызов функции.На этом этапе наборы создаются для каждого аргумента в вызове функции, и можно определить, существует ли неоднозначная перегрузка.Это означает, что неоднозначности могут оставаться в коде до тех пор, пока они не будут вызваны конкретным вызовом функции.