16 Overloading [over]

16.4 Address of overloaded function [over.over]

Использование имени перегруженной функции без аргументов разрешается в определенных контекстах для функции, указателя на функцию или указателя на функцию-член для конкретной функции из набора перегрузки. Имя шаблона функции считается именем набора перегруженных функций в таких контекстах. Функция с типом F выбирается для типа функции FT целевого типа, требуемого в контексте, если F (после возможного применения function pointer conversion) идентична FT. [ Note: То есть класс, членом которого является функция, игнорируется при сопоставлении типа указателя на функцию-член. ] Цель может бытьend note

Перед именем перегруженной функции может стоять & оператор. Имя перегруженной функции не должно использоваться без аргументов в контекстах, отличных от перечисленных. [ Note: Любой лишний набор круглых скобок, окружающий имя перегруженной функции, игнорируется ([expr.prim]). ]end note

Если имя является шаблоном функции, выполняется вывод аргументов шаблона ([temp.deduct.funcaddr]), и если вывод аргументов завершается успешно, результирующий список аргументов шаблона используется для генерации одной специализации шаблона функции, которая добавляется к набору рассматриваемых перегруженных функций. [ Note: Как описано в [temp.arg.explicit], если вывод не удастся и за именем шаблона функции следует явный список аргументов шаблона, template-id затем проверяется, идентифицирует ли он конкретную специализацию шаблона функции. Если это так, то template-id считается lvalue для этой специализации шаблона функции. Тип цели не используется в этом определении. ]end note

Функции, не являющиеся членами, и статические функции-члены соответствуют целям типа указателя функции или ссылки на тип функции. Нестатические функции-члены соответствуют целям указателя на тип функции-члена. Если выбрана нестатическая функция-член, ссылка на имя перегруженной функции должна иметь форму указателя на член, как описано в [expr.unary.op].

Если выбрано более одной функции, любые специализации шаблона функции в наборе удаляются, если набор также содержит функцию, которая не является специализацией шаблона функции, и любая заданная специализация шаблона функции удаляется, F1 если набор содержит вторую специализацию шаблона функции, чья шаблон функции является более специализированным, чем шаблон функции в F1 соответствии с правилами частичного упорядочивания [temp.func.order]. После таких исключений, если таковые имеются, останется только одна выбранная функция.

[Example:

int f(double);
int f(int);
int (*pfd)(double) = &f;        // selects f(double)
int (*pfi)(int) = &f;           // selects f(int)
int (*pfe)(...) = &f;           // error: type mismatch
int (&rfi)(int) = f;            // selects f(int)
int (&rfd)(double) = f;         // selects f(double)
void g() {
  (int (*)(int))&f;             // cast expression as selector
}

Инициализация pfe неправильно сформирована, потому что не был объявленf() тип with int(...), а не из-за какой-либо двусмысленности. Другой пример:

struct X {
  int f(int);
  static int f(long);
};

int (X::*p1)(int)  = &X::f;     // OK
int    (*p2)(int)  = &X::f;     // error: mismatch
int    (*p3)(long) = &X::f;     // OK
int (X::*p4)(long) = &X::f;     // error: mismatch
int (X::*p5)(int)  = &(X::f);   // error: wrong syntax for
                                // pointer to member
int    (*p6)(long) = &(X::f);   // OK

end example]

[ Note: Если обеf() и g()являются перегруженными функциями, для разрешения необходимо учитывать перекрестное произведение возможностей f(&g)или эквивалентное выражение f(g). ]end note

[ Note: Даже если B это общедоступная база D, у нас есть

D* f();
B* (*p1)() = &f;                // error

void g(D*);
void (*p2)(B*) = &g;            // error

end note]