Использование имени перегруженной функции без аргументов разрешается в определенных контекстах для функции, указателя на функцию или указателя на функцию-член для конкретной функции из набора перегрузки. Имя шаблона функции считается именем набора перегруженных функций в таких контекстах. Функция с типом F выбирается для типа функции FT целевого типа, требуемого в контексте, если F (после возможного применения function pointer conversion) идентична FT. [ Note: То есть класс, членом которого является функция, игнорируется при сопоставлении типа указателя на функцию-член. ] Цель может быть — end note
объект или ссылка инициализируется ([dcl.init], [dcl.init.ref], [dcl.init.list]),
левая сторона assignment,
параметр функции ([expr.call]),
параметр a user-defined operator,
возвращаемое значение функции, операторной функции или преобразования ([stmt.return]),
явное преобразование типа ([expr.type.conv], [expr.static.cast], [expr.cast]), или
не тип template-parameter([temp.arg.nontype]).
Перед именем перегруженной функции может стоять & оператор. Имя перегруженной функции не должно использоваться без аргументов в контекстах, отличных от перечисленных. [ 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