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
Fis selected for the function typeFTof 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
Sremains, all function template specializations inSare eliminated ifSalso contains a non-template function.
|
(since C++20) |
- Any given function template specialization spec is eliminated if
Scontains 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]