Address of an overloaded function
Besides function-call expressions, where overload resolution takes place, the name of an overloaded function may appear in the following 7 contexts:
Context | Target |
---|---|
initializer in a declaration of an object or reference | the object or reference being initialized |
on the right-hand-side of an assignment expression | the left-hand side of the assignment |
as a function call argument | the function parameter |
as a user-defined operator argument | the operator parameter |
the return statement
|
the return value of a function or conversion |
explicit cast or static_cast argument
|
the corresponding cast |
non-type template argument | the corresponding template parameter |
In each context, the name of an overloaded function may be preceded by address-of operator &
and may be enclosed in a redundant set of parentheses.
If the target type contains a placeholder type, placeholder type deduction is performed, and the following description uses the deduced type as target type. |
(since C++26) |
Selecting functions
When the address of an overloaded function is taken, a set S
of functions is selected from the overload set referred to by the name of the overload function:
- If there is no target, all non-template functions named are selected.
- Otherwise, a non-template function with type
F
is selected for the function typeFT
of the target type ifF
(after possibly applying the function pointer conversion)(since C++17) is identical toFT
.[1] - The specialization (if any) generated by template argument deduction for each function template named is also added to
S
.
If the target is of function pointer type or reference to function type, S
can only include non-member functions, explicit object member functions(since C++23) and static member functions. If the target is of pointer-to-member-function type, S
can only include implicit object member functions.
- ↑ In other words, the class of which the function is a member is ignored if the target type is a pointer-to-member-function type.
Eliminating functions
After forming the set S
, functions are elimiated in the following order:
|
(since C++20) |
- If more than one function in
S
remains, all function template specializations inS
are eliminated ifS
also contains a non-template function.
|
(since C++20) |
- Any given function template specialization spec is eliminated if
S
contains a second function template specialization whose function template is more specialized than the function template of spec.
After such eliminations (if any), exactly one selected function should remain in S
. Otherwise, the program is ill-formed.
Example
int f(int) { return 1; } int f(double) { return 2; } void g(int(&f1)(int), int(*f2)(double)) { f1(0); f2(0.0); } template<int(*F)(int)> struct Templ {}; struct Foo { int mf(int) { return 3; } int mf(double) { return 4; } }; struct Emp { void operator<<(int (*)(double)) {} }; int main() { // 1. initialization int (*pf)(double) = f; // selects int f(double) int (&rf)(int) = f; // selects int f(int) int (Foo::*mpf)(int) = &Foo::mf; // selects int mf(int) // 2. assignment pf = nullptr; pf = &f; // selects int f(double) // 3. function argument g(f, f); // selects int f(int) for the 1st argument // and int f(double) for the second // 4. user-defined operator Emp{} << f; //selects int f(double) // 5. return value auto foo = []() -> int (*)(int) { return f; // selects int f(int) }; // 6. cast auto p = static_cast<int(*)(int)>(f); // selects int f(int) // 7. template argument Templ<f> t; // selects int f(int) // prevent “unused variable” warnings as if by [[maybe_unused]] [](...){}(pf, rf, mpf, foo, p, t); }
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 202 | C++98 | non-type template argument was not a context of taking the address of an overloaded function |
it is |
CWG 250 | C++98 | function template specializations generated with non-deduced template arguments were not selected from the overload set |
also selected |
CWG 1153 | C++98 | it was unclear whether a given function type matches the target type | made clear |
CWG 1563 | C++11 | it was unclear whether list-initialization is a context of taking the address of an overloaded function |
made clear |
References
- C++23 standard (ISO/IEC 14882:2024):
- 12.3 Address of overloaded function [over.over]
- C++20 standard (ISO/IEC 14882:2020):
- 12.5 Address of overloaded function [over.over]
- C++17 standard (ISO/IEC 14882:2017):
- 16.4 Address of overloaded function [over.over]
- C++14 standard (ISO/IEC 14882:2014):
- 13.4 Address of overloaded function [over.over]
- C++11 standard (ISO/IEC 14882:2011):
- 13.4 Address of overloaded function [over.over]
- C++98 standard (ISO/IEC 14882:1998):
- 13.4 Address of overloaded function [over.over]