Overload resolution
In order to compile a function call, the compiler must first perform name lookup, which, for functions, may involve argument-dependent lookup, and for function templates may be followed by template argument deduction. If these steps produce more than one candidate function, then overload resolution is performed to select the function that will actually be called.
In general, the candidate function whose parameters match the arguments most closely is the one that is called.
Contents |
[edit] Details
Before overload resolution begins, the functions selected by name lookup and template argument deduction are combined to form the set of candidate functions (the exact criteria depend on the context in which overload resolution takes place, see below).
If any candidate function is a member function (static or non-static), but not a constructor, it is treated as if it has an extra parameter (implicit object parameter) which represents the object for which they are called and appears before the first of the actual parameters.
Similarly, the object on which a member function is being called, is prepended to the argument list as the implied object argument
For member functions of class X
, the type of the implicit object parameter is affected by cv-qualifications and ref-qualifications of the member function as described in member_functions
The user-defined conversion functions are considered to be members of the implied object argument for the purpose of determining the type of the implicit object parameter.
The member functions introduced by a using-declaration into a derived class are considered to be members of the derived class for the purpose of defining the type of the implicit object parameter.
For the static member functions, the implicit object parameter is considered to match any object: its type is not examined and no conversion sequence is attempted for it.
For the rest of overload resolution, the implied object argument is indistinguishable from other arguments, but the following special rules apply to the implicit object parameter:
This section is incomplete Reason: small illustrative examples |
[edit] Candidate functions
The set of candidate functions and the list of arguments is prepared in a unique way for each of the contexts where overload resolution is used:
[edit] Call to a named function
If E
in a function call expression E(args)
names a set of overloaded functions and/or function templates (but not callable objects), the following rules are followed:
- If the expression
E
has the formPA->B
orA.B
(where A has class type cv T), thenB
is looked up as a member function ofT
. The function declarations found by that lookup are the candidate functions. The argument list for the purpose of overload resolution has the implied object argument of type cv T. - If the expression
E
is a primary expression, the name is looked up following normal rules for function calls (which may involve ADL). The function declarations found by this lookup are (due to the way lookup works) either:
- a) all non-member functions (in which case the argument list for the purpose of overload resolution is exactly the argument list used in the function call expression)
- b) all member functions of some class
T
, in which case, if this is in scope and refers toT
,*this
is used as the implied object argument. Otherwise (ifthis
is not in scope or does not point toT
, a fake object of typeT
is used as the implied object argument, and if overload resolution subsequently selects a non-static member function, the program is ill-formed.
[edit] Call to a class object
If E
in a function call expression E(args)
has class type cv T
, then
- The function-call operators of T are obtained by ordinary lookup of the name operator() in the context of the expression
(E).operator()
, and every declaration found is added to the set of candidate functions. - For each non-explicit user-defined conversion function in
T
or in a base ofT
(unless hidden), whose cv-qualifiers is same or greater thanT
's cv-qualifiers, and where the conversion function converts to:
-
- to pointer-to-function
- to reference-to-pointer-to-function
- to reference-to-function
- then a surrogate function with a unique name whose first parameter is the result of the conversion, the remaining parameters are the parameter-list accepted by the result of the conversion, and the return type is the return type of the result of the conversion, is added to the set of candidate functions. If this surrogate function is selected by the subsequent overload resolution, then the user-defined conversion function will be called and then the result of the conversion will be called.
In any case, the argument list for the purpose of overload resolution is the argument list of the function call expression preceded by the implied object argument E
(when matching against the surrogate function, the user-defined conversion will automatically convert the implied object argument to the first argument of the surrogate function).
int f1(int); int f2(float); struct A { using fp1 = int(*)(int); operator fp1() { return f1; } // conversion function to pointer to function using fp2 = int(*)(float); operator fp2() { return f2; } // conversion function to pointer to function } a; int i = a(1); // calls f1 via pointer returned from conversion function
[edit] Call to an overloaded operator
If at least one of the arguments to an operator in an expression has a class type or an enumeration type, both builtin operators and user-defined operator overloads participate in overload resolution, with the set of candidate functions selected as follows:
For a unary operator @
whose argument has type T1
(after removing cv-qualifications), or binary operator @
whose left operand has type T1
and right operand of type T2
(after removing cv-qualifications), three sets of candidate functions are prepared:
T1
is a complete class or a class currently being defined, the set of member candidates is the result of qualified name lookup of T1::operator@
. In all other cases, the set of member candidates is empty. operator@
in the context of the expression (which may involve ADL), except that member function declarations are ignored and do not prevent the lookup from continuing into the next enclosing scope. If both operands of a binary operator or the only operand of a unary operator has enumeration type, the only functions from the lookup set that become non-member candidates are the ones whose parameter has that enumeration type (or reference to that enumeration type)The set of candidate functions to be submitted for overload resolution is a union of the three sets above. The argument list for the purpose of overload resolution consists of the operands of the operator except for operator->
, where the second operand is not an argument for the function call (see member access operator).
struct A { operator int(); // user-defined conversion }; A operator+(const A&, const A&); // non-member user-defined operator void m() { A a, b; a + b; // member-candidates: none // non-member candidates: operator+(a,b) // built-in candidates: int(a) + int(b) // overload resolution chooses operator+(a,b) }
If the overload resolution selects a built-in candidate, the user-defined conversion sequence from an operand of class type is not allowed to have a second standard conversion sequence: the user-defined conversion function must give the expected operand type directly:
struct Y { operator int*(); }; // Y is convertible to int* int *a = Y() + 100.0; // error: no operator+ between pointer and double
For operator,, the unary operator&, and operator->, if there are no viable functions (see below) in the set of candidate functions, then the operator is reinterpreted as a built-in.
[edit] Initialization by constructor
When an object of class type is direct-initialized, the candidate functions are all constructors of the class being initialized. The argument list is the expression list of the initializer.
When an object of class type is copy-initialized from an object of the same or derived class type, the candidate functions are all converting constructors of the class being initialized. The argument list is the expression of the initializer.
[edit] Copy-initialization by conversion
If copy-initialization of an object of class type requires that a user-defined conversion function is called to convert the initializer expression of type cv S
to the type cv T
of the object being initialized, the following functions are candidate functions:
- all converting constructors of
T
- the non-explicit conversion functions from
S
and its base classes (unless hidden) toT
or class derived fromT
or a reference to such. If this copy-initialization is part of the direct-initialization sequence of cvT
(initializing a reference to be bound to the first parameter of a constructor that takes a reference to cvT
), then explicit conversion functions are also considered.
Either way, the argument list for the purpose of overload resolution consists of a single argument which is the initializer expression, which will be compared against the first argument of the constructor or against the implicit object argument of the conversion function.
[edit] Non-class initialization by conversion
When initialization of an object of non-class type cv1 T
requires a user-defined conversion function to convert from an initializer expression of class type cv S
, the following functions are candidates:
- the non-explicit user-defined conversion functions of
S
and its base classes (unless hidden) that produce typeT
or a type convertible toT
by a standard conversion sequence, or a reference to such type. cv qualifiers on the returned type are ignored for the purpose of selecting candidate functions. - if this is direct-initialization, the explicit user-defined conversion functions of
S
and its base classes (unless hidden) that produce typeT
or a type convertible toT
by a qualification conversion, , or a reference to such type, are also considered.
Either way, the argument list for the purpose of overload resolution consists of a single argument which is the initializer expression, which will be compared against the implicit object argument of the conversion function.
[edit] Reference initialization by conversion
During reference initialization, where the reference to cv1 T
is bound to the glvalue or class prvalue result of a conversion from the initializer expression from the class type cv2 S
, the following functions are selected for the candidate set:
- the non-explicit user-defined conversion functions of
S
and its base classes (unless hidden) to the type
-
- (when initializing lvalue reference or rvalue reference to function) lvalue reference to cv2
T2
- (when initializing rvalue reference or lvalue reference to function) cv2
T2
or rvalue reference to cv2T2
- (when initializing lvalue reference or rvalue reference to function) lvalue reference to cv2
- where cv2 T2 is reference-compatible with cv1 T
- for direct initializaton, the explicit user-defined conversion functions are also considered if T2 is the same type as T or can be converted to type T with a qualification conversion.
Either way, the argument list for the purpose of overload resolution consists of a single argument which is the initializer expression, which will be compared against the implicit object argument of the conversion function.
[edit] List-initialization
When an object of non-aggregate class type T
is list-initialized, two-phase overload resolution takes place.
- at phase 1, the candidate functions are all initializer-list constructors of
T
and the argument list for the purpose of overload resolution consists of a single initializer list argument - if overload resolution fails at phase 1, phase 2 is entered, where the candidate functions are all constructors of
T
and the argument list for the purpose of overload resolution consists of the individual elements of the initializer list.
If the initializer list is empty and T
has a default constructor, phase 1 is skipped.
In copy-list-initialization, if phase 2 selects an explicit constructor, the initialization is ill-formed (as opposed to all over copy-initializations where explicit constructors are not even considered).
[edit] Viable functions
Given the set of candidate functions, constructed as described above, the next step of overload resolution is examining arguments and parameters to reduce the set to the set of viable functions
To be included in the set of viable functions, the candidate function must satisfy the following:
M
arguments, the candidate function that has exactly M
parameters is viableM
parameters, but has an ellipsis parameter, it is viable.M
parameters and the M+1
'st parameter and all parameters that follow must have default arguments, it is viable. For the rest of overload resolution, the parameter list is truncated at M.[edit] Best viable function
For each pair of viable function F1
and F2
, the implicit conversion sequences from the i
-th parameter to i
-th argument are ranked to determine which one is better (except the first argument, the implicit object argument for static member functions has no effect on the ranking)
F1
is determined to be a better function than F2
if implicit conversions for all arguments of F1 are not worse than the implicit conversions for all arguments of F2, and
These pair-wise comparisons are applied to all viable functions. If exactly one viable function is better than all others, overload resolution succeeds and this function is called. Otherwise, compilation fails.
void Fcn(const int*, short); // overload #1 void Fcn(int*, int); // overload #2 int i; short s = 0; void f() { Fcn(&i, 1L); // 1st argument: &i -> int* is better than &i -> const int* // 2nd argument: 1L -> short and 1L -> int are equivalent // calls Fcn(int*, int) Fcn(&i,’c’); // 1st argument: &i -> int* is better than &i -> const int* // 2nd argument: 'c' -> int is better than 'c' -> short // calls Fcn(int*, int) Fcn(&i, s); // 1st argument: &i -> int* is better than &i -> const int* // 2nd argument: s -> short is better than s -> int // no winner, compilation error }
[edit] Ranking of implicit conversion sequences
The argument-parameter implicit conversion sequences considered by overload resolution correspond to implicit conversions used in copy initialization (for non-reference parameters), except that when considering conversion to the implicit object parameter or to the left-hand side of assignment operator, conversions that create temporary objects are not considered.
Each type of standard conversion sequence is assigned one of three ranks:
The rank of the standard conversion sequence is the worst of the ranks of the standard conversions it holds (there may be up to three conversions)
Binding of a reference parameter directly to the argument expression is either Identity or a derived-to-base Conversion:
struct Base {}; struct Derived : Base {} d; int f(Base&); // overload #1 int f(Derived&); // overload #2 int i = f(d); // d -> Derived& has rank Exact Match // d -> Base& has rank Conversion // calls f(Derived&)
Since ranking of conversion sequences operates with types and value categories only, a bit field can bind to a reference argument for the purpose of ranking, but if that function gets selected, it will be ill-formed.
S1
is better than a standard conversion sequence S2
ifS1
is a subsequence of S2
, excluding lvalue transformations. The identity conversion sequence is considered a subsequence of any other conversionS1
is better thank the rank of S2
S1
and S2
are binding to a reference parameter to something other than the implicit object parameter of a ref-qualified member function, and S1
binds an rvalue reference to an rvalue while S2
binds an rvalue reference to an rvalue
int i; int f1(); int g(const int&); // overload #1 int g(const int&&); // overload #2 int j = g(i); // lvalue int -> const int& is the only valid conversion int k = g(f1()); // rvalue int -> const int&& better than rvalue int -> const int&
S1
and S2
are binding to a reference parameter and S1
binds an lvalue reference to function while S2
binds an rvalue reference to function.
int f(void(&)()); // overload #1 int f(void(&&)()); // overload #2 void g(); int i1 = f(g); // calls #1
S1
and S2
are binding to a reference parameters only different in top-level cv-qualification, and S1
's type is less cv-qualified than S2
's.
int f(const int &); // overload #1 int f(int &); // overload #2 (both references) int g(const int &); // overload #1 int g(int); // overload #2 int i; int j = f(i); // lvalue i -> int& is better than lvalue int -> const int& // calls f(int&) int k = g(i); // lvalue i -> const int& ranks Exact Match // lvalue i -> rvalue int ranks Exact Match // ambiguous overload: compilation error
S1
is a subset of the cv-qualification of the result of S2
int f(const int*); int f(int*); int i; int j = f(&i); // &i -> int* is better than &i -> const int*, calls f(int*)
U1
is better than a user-defined conversion sequence U2
if they call the same constructor/user-defined conversion function or initialize the same class with aggregate-initialization, and in either case the second standard conversion sequence in U1
is better than the second standard conversion sequence in U2
struct A { operator short(); // user-defined conversion function } a; int f(int); // overload #1 int f(float); // overload #2 int i = f(a); // A -> short, followed by short -> int (rank Promotion) // A -> short, followed by short -> float (rank Conversion) // calls f(int)
L1
is better than list-initialization sequence L2
if L1
initializes an std::initializer_list parameter, while L2
does not.
std::vector<std::size_t> v{10, 20}; // calls vector<size_t>(initializer_list<size_t>) // not vector<size_t>(size_t, size_t)
If two conversion sequences are indistinguishable because they have the same rank, the following additional rules apply:
Mid
is derived (directly or indirectly) from Base
, and Derived
is derived (directly or indirectly) from Mid
Ambiguous conversion sequences are ranked as user-defined conversion sequences because multiple conversion sequences for an argument can exist only if they involve different user-defined conversions:
class B; class A { A (B&);}; // converting constructor class B { operator A (); }; // user-defined conversion function class C { C (B&); }; // converting constructor void f(A) { } // overload #1 void f(C) { } // overload #2 B b; f(b); // B -> A via ctor or B -> A via function (ambiguous conversion) // b -> C via ctor (user-defined conversion) // the conversions for overload #1 and for overload #2 // are indistinguishable; compilation fails
[edit] Implicit conversion sequence in list-initialization
In list initialization, the argument is a braced-init-list, which isn't an expression, so the implicit conversion sequence into the parameter type for the purpose of overload resolution is decided by the following special rules:
- If the parameter type is std::initializer_list<X>, and there is an non-narrowing implicit conversion from every element of the initializer list to
X
, the implicit conversion sequence for the purpose of overload resolution is the worst conversion necessary. If the braced-init-list is empty, the conversion sequence is the identity conversion.
struct A { A(std::initializer_list<double>); // #1 A(std::initializer_list<complex<double>>); // #2 A(std::initializer_list<std::string>); // #3 }; A a{1.0,2.0}; // selects #1 (rvalue double -> double: identity conv) void g(A); g({"foo","bar"}); // selects #3 (lvalue const char[4] -> std::string: user-def conv)
- Otherwise, if the parameter type is T[N] (this only happens for references to arrays), the initializer list must have N or less elements (and if it's less, T must be default-constructible), and the worst implicit conversion necessary to convert every element of the list to
T
is the one used.
typedef int IA[3]; void h(const IA&); h({1,2,3}); // int->int identity conversion
- Otherwise, if the parameter type is a non-aggregate class type
X
, overload resolution picks the constructor of X to initialize from the argument initializer list, and then the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion. If multiple constructors are viable but none is better than the others, the implicit conversion sequence is the ambiguous conversion sequence.
struct A { A(std::initializer_list<int>); }; void f(A); struct B { B(int, double); }; void g(B); g({’a’,’b’}); // calls g(B(int,double)), user-defined conversion // g({1.0, 1,0}); // error: double->int is narrowing, not allowed in list-init void f(B); // f({’a’,’b’}); // f(A) and f(B) both user-defined conversions
- Otherwise, if the parameter type is an aggregate which can be initialized from the initializer list according by aggregate initialization, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
struct A { int m1; double m2;}; void f(A); f({’a’,’b’}); // calls f(A(int,double)), user-defined conversion
- Otherwise, if the parameter is a reference, reference initialization rules apply
struct A { int m1; double m2; }; void f(const A&); f({’a’,’b’}); // temporary created, f(A(int,double)) called. User-defined conversion
- Otherwise, if the parameter type is not a class and the initializer list has one element, the implicit conversion sequence is the one required to convert the element to the parameter type
- Otherwise, if the parameter type is not a class type and if the initializer list has no elements, the implicit conversion sequence is the identity conversion.
[edit] See also
[edit] References
- C++11 standard (ISO/IEC 14882:2011):
-
- 13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]