[over.over]

# 12 Overloading [[over]](./#over)

## 12.3 Address of an overload set [over.over]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3155)

An expression
that designates an overload set S and
that appears without arguments
is resolved to
a function,
a pointer to function, or
a pointer to member function
for a specific function
that is chosen from a set of functions selected from S determined based on the target type required in the context (if any),
as described below[.](#1.sentence-1)

The target can be

- [(1.1)](#1.1)

an object or reference being initialized ([[dcl.init]](dcl.init "9.5 Initializers"), [[dcl.init.ref]](dcl.init.ref "9.5.4 References"), [[dcl.init.list]](dcl.init.list "9.5.5 List-initialization")),

- [(1.2)](#1.2)

the left side of an assignment ([[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators")),

- [(1.3)](#1.3)

a parameter of a function ([[expr.call]](expr.call "7.6.1.3 Function call")),

- [(1.4)](#1.4)

a parameter of a [user-defined operator](over.oper "12.4 Overloaded operators [over.oper]"),

- [(1.5)](#1.5)

the return value of a function, operator function, or conversion ([[stmt.return]](stmt.return "8.8.4 The return statement")),

- [(1.6)](#1.6)

an explicit type conversion ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)")), or

- [(1.7)](#1.7)

a constant template parameter ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#1.sentence-2)

If the target type contains a placeholder type,
placeholder type deduction is performed ([[dcl.type.auto.deduct]](dcl.type.auto.deduct "9.2.9.7.2 Placeholder type deduction")), and
the remainder of this subclause uses the target type so deduced[.](#1.sentence-3)

The expression can be preceded by the & operator[.](#1.sentence-4)

[*Note [1](#note-1)*:

Any redundant set of parentheses surrounding the function name is
ignored ([[expr.prim.paren]](expr.prim.paren "7.5.4 Parentheses"))[.](#1.sentence-5)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3193)

If there is no target, all non-template functions named are selected[.](#2.sentence-1)

Otherwise, a non-template function with type F is selected for the function type FT of the target type
if F (after possibly applying the function pointer conversion ([[conv.fctptr]](conv.fctptr "7.3.14 Function pointer conversions")))
is identical to FT[.](#2.sentence-2)

[*Note [2](#note-2)*:

That is, the class of which the function is a member is ignored when matching a
pointer-to-member-function type[.](#2.sentence-3)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3205)

The specialization, if any, generated by template argument
deduction ([[temp.over]](temp.over "13.10.4 Overload resolution"), [[temp.deduct.funcaddr]](temp.deduct.funcaddr "13.10.3.3 Deducing template arguments taking the address of a function template"), [[temp.arg.explicit]](temp.arg.explicit "13.10.2 Explicit template argument specification"))
for each function template named
is added to the set of selected functions considered[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3211)

Non-member functions,
static member functions, and
explicit object member functions
match targets of function pointer type or
reference to function type[.](#4.sentence-1)

Implicit object member functions match targets of
pointer-to-member-function type[.](#4.sentence-2)

[*Note [3](#note-3)*:

If an implicit object member function is chosen,
the result can be used only to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators"))[.](#4.sentence-3)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3225)

All functions with
associated constraints
that are not satisfied ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations"))
are eliminated from the set of selected functions[.](#5.sentence-1)

If more than one function in the set remains,
all function template specializations
in the set
are eliminated if the set also contains a function that is not a
function template specialization[.](#5.sentence-2)

Any given non-template functionF0 is eliminated if the set contains a second
non-template function that
is more partial-ordering-constrained thanF0 ([[temp.constr.order]](temp.constr.order "13.5.5 Partial ordering by constraints"))[.](#5.sentence-3)

Any given
function template specializationF1 is eliminated if the set contains a second
function template specialization whose function template
is more specialized than the
function template ofF1 according to
the partial ordering rules of [[temp.func.order]](temp.func.order "13.7.7.3 Partial ordering of function templates")[.](#5.sentence-4)

After such eliminations,
if any, there shall remain exactly one selected function[.](#5.sentence-5)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3254)

[*Example [1](#example-1)*: 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 mismatchint (&rfi)(int) = f; // selects f(int)int (&rfd)(double) = f; // selects f(double)void g() {(int (*)(int))&f; // cast expression as selector}

The initialization ofpfe is ill-formed because nof() with typeint(...) has been declared, and not because of any ambiguity[.](#6.sentence-1)

â *end example*]

[*Example [2](#example-2)*: struct X {int f(int); static int f(long);};

int (X::*p1)(int) = &X::f; // OKint (*p2)(int) = &X::f; // error: mismatchint (*p3)(long) = &X::f; // OKint (X::*p4)(long) = &X::f; // error: mismatchint (X::*p5)(int) = &(X::f); // error: wrong syntax for// pointer to memberint (*p6)(long) = &(X::f); // OK â *end example*]

[*Example [3](#example-3)*: template<bool B> struct X {void f(short) requires B; void f(long); template<typename> void g(short) requires B; template<typename> void g(long);};void test() {&X<true>::f; // error: ambiguous; constraints are not considered&X<true>::g<int>; // error: ambiguous; constraints are not considered} â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3310)

[*Note [4](#note-4)*:

If f and g are both overload sets,
the Cartesian product of possibilities is considered
to resolve f(&g), or the equivalent expression f(g)[.](#7.sentence-1)

â *end note*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3317)

[*Note [5](#note-5)*:

Even if B is a public base of D,
we haveD* f();
B* (*p1)() = &f; // errorvoid g(D*);void (*p2)(B*) = &g; // error

â *end note*]
