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 thereturn
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 functionsWhen 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:
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]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.
After forming the set S
, functions are elimiated in the following order:
S
.S
remains, all function template specializations in S
are eliminated if S
also contains a non-template function.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.
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 contextRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4