Namespaces
Variants
Actions

Address of an overloaded function

From cppreference.com
< cpp‎ | language
 
 
C++ language
General topics
 
 

Besides function-call expressions, where overload resolution takes place, the name of an overloaded function may appear in the following 7 contexts:

# Context Target
1 initializer in a declaration of an object or reference the object or reference being initialized
2 on the right-hand-side of an built-in assignment expression the left-hand side of the built-in assignment
3 as a function call argument the function parameter
4 as a user-defined operator argument the operator parameter
5 the return statement the return value of a function or conversion
6 explicit cast or static_cast argument the corresponding cast
7 constant 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)

[edit] 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 type FT of the target type if F (after possibly applying the function pointer conversion)(since C++17) is identical to FT.[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.

  1. 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.

[edit] Eliminating functions

After forming the set S, functions are elimiated in the following order:

  • All functions with associated constraints that are not satisfied are eliminated from the S.
(since C++20)
  • If more than one function in S remains, all function template specializations in S are eliminated if S 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.

[edit] Example

Run this code
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);
}

[edit] 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 constant 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

[edit] 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]

AltStyle によって変換されたページ (->オリジナル) /