R.13 Перегрузка
R.13 Перегрузка
Говорят, что имя перегружено, если для него задано несколько различных описаний функций в одной области видимости. При использовании имени выбор правильной функции производится путем сопоставления типов формальных параметров с типами фактических параметров, например:
double abs(double);
int abs(int);
abs(1); // вызов abs(int)
abs(1.0); // вызов abs(double)
Поскольку при любом типе T и для самого T, для и T& допустимо одно и то же множество инициализирующих значений, функции, типы параметров которых различаются только использованием, или не использованием ссылки, не могут иметь одинаковые имена, например:
int f(int i)
{
//…
}
int f(int& r) // ошибка: типы функций
{ // недостаточно различны
//…
}
Аналогично, поскольку для любом типе T для самого T, const T и volatile T допустимо одно и то же множество инициализирующих значений, функции, типы параметров которых отличаются только указанной спецификацией, не могут иметь одинаковые имена. Однако, различить const T&, volatile T& и просто T& можно, поэтому допустимы определения функций с одним именем, которые различаются только в указанном отношении. Аналогично, допустимы определения функций с одним именем, типы параметров которых различаются только как типы вида const T*, volatile T* и просто T*.
Не могут иметь одинаковые имена функции, которые отличаются только типом возвращаемого значения.
Не могут иметь одинаковые имена функции-члены, одна из которых статическая, а другая нет (§R.9.4).
С помощью конструкции typedef не создаются новые типы, а только определяется синоним типа (§R.7.1.3), поэтому функции, которые отличаются только за счет использования типов, определенных с помощью typedef, не могут иметь одинаковые имена. Приведем пример:
typedef int Int;
void f(int i) {/*… */}
void f(Int i) {/*… */} // ошибка: переопределение f
С другой стороны все перечисления считаются разными типами, и с их помощью можно различить перегруженные функции, например:
enum E { a };
void f(int i) {/*… */}
void f(E i) {/*… */}
Типы параметров, которые различаются только тем, что в одном используется указатель *, а в другом массив [], считаются идентичными. Напомним, что для типа параметра важны только второй и последующие индексы многомерного массива (§R.8.2.4). Подтвердим сказанное примером:
f(char*);
f(char[]); // идентично f(char*);
f(char[7]); // идентично f(char*);
f(char[9]); // идентично f(char*);
g(char(*)[10]);
g(char[5][10]); // идентично g(char(*)[10]);
g(char[7][10]); // идентично g(char(*)[10]);
g(char(*)[20]); // отлично от g(char(*)[10]);