void Foo();
char Foo(); // ошибка
void Foo(int x);
void Foo(int x) noexcept; // ошибка
void Foo(double x);
void Foo(double) = delete; // ошибка
Но несколько идентичных объявлений допустимы, компилятор просто игнорирует копии.
Также надо учитывать, что компилятор выполняет некоторые стандартные преобразования типов параметров функций. Для типа массива выполняется сведение (decay) к указателю, поэтому
void Foo(int x[4]);
void Foo(int x[]);
void Foo(int *x);
не перегруженные функции, это одно и то же.
Параметры типа функция сводятся к указателю на функцию.
Для параметров, передаваемых по значению, удаляется квалификатор const (и volatile), поэтому
void Foo(int x);
void Foo(const int x);
не перегруженные функции, это одно и то же.
В общих чертах алгоритм поиска функции можно описать следующим образом. На первом этапе компилятор осуществляет поиск (lookup) тех перегруженных функций, которые по правилам языка допустимы для данного вызова (candidate functions). В случае шаблонов выполняется еще вывод аргументов шаблона (template argument deduction). У этих функций количество параметров должно совпадать с количеством аргументов и тип аргументов должен совпадать с типом параметров (или существовать неявное преобразование типа аргументов к типу параметров). Если таких функций не найдено, поиск завершается ошибкой. Если найдена ровно одна функция, то поиск завершается успешно. Если найдено несколько функций, то начинается следующий этап, компилятор пытается выбрать ту, которая подходит «лучше всего» для данных аргументов (match the arguments most closely). Этот этап называется разрешением перегрузки (overload resolution). Если такая функция найдена, то разрешение перегрузки завершается успешно, иначе возникает ошибка (ambiguous call to overloaded function). Рассмотрим пример:
Do'stlaringiz bilan baham: |