Правила связывания
Если требуется реализация одной и той же операции для данных различных типов, то можно определить нескольких функций с одним и тем же именем. Такие функции называют перегруженными. Перегруженные функции должны быть объявлены в одной области видимости (блоке, классе или пространстве имен) и иметь различные сигнатуры (список типов параметров функции в скобках). Сигнатуры должны отличаться количеством параметров или их типами. Тип возвращаемого значения в сигнатуру не входит.
Связывание – это процесс выбора экземпляра функции из набора в одной области видимости, который соответствует набору аргументов при ее вызове. Различают раннее (статическое, во время компиляции) и позднее (динамическое, во время выполнения) связывание. В С++ используется раннее связывание, но механизм виртуальных методов можно рассматривать как позднее связывание по первому, скрытому аргументу.
Выбор функции при связывании происходит на основе следующих приоритетов:
- Точное соответствие.
- Повышение точности: char, short, wchar_t, enum, bool `→` int; float `→` double.
- Стандартные преобразования: любой числовой тип в любой числовой тип (близость типов во внимание не принимается); любой указатель в void *; константа 0 к любому числовому типу или указателю; указатель или ссылка на производный класс к указателю или ссылке на базовый класс.
- Преобразования через конструкторы-преобразователи или операции преобразования, определенные программистом.
- Соответствие ... (специальное обозначение для любого количества параметров, см. printf).
Выбирается функция или метод с большим точным числом соответствий, при одинаковом количестве точных соответствий – рассматривается количество повышений точности, затем учитывается число стандартных преобразований и т.д. Если две или более функции из набора получают одинаковый приоритет, то компилятор выводит сообщение об ошибке.
void f(double); //
void f(const char *); //
void f(...); //
int main()
{
int a[10];
float b;
f(b); //
f('A'); //
f("A"); //
f(0); //
f(1); //
f(a); //
}