printПерегрузка функций и операций

printПравила связывания

Если требуется реализация одной и той же операции для данных различных типов, то можно определить нескольких функций с одним и тем же именем. Такие функции называют перегруженными. Перегруженные функции должны быть объявлены в одной области видимости (блоке, классе или пространстве имен) и иметь различные сигнатуры (список типов параметров функции в скобках). Сигнатуры должны отличаться количеством параметров или их типами. Тип возвращаемого значения в сигнатуру не входит.

Связывание – это процесс выбора экземпляра функции из набора в одной области видимости, который соответствует набору аргументов при ее вызове. Различают раннее (статическое, во время компиляции) и позднее (динамическое, во время выполнения) связывание. В С++ используется раннее связывание, но механизм виртуальных методов можно рассматривать как позднее связывание по первому, скрытому аргументу.

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