Namespaces
Variants
Views
Actions

Overload resolution

From cppreference.com
< cpp‎ | language
Revision as of 06:35, 22 August 2013 by Cubbi (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

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

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:

1) the argument for the implicit object parameter cannot be held in a temporary object
2) user-defined conversions cannot be applied to the implicit object parameter
3) rvalues can be bound to non-const implicit object parameter (unless this is for a ref-qualified member function) and does not affect the ranking of the implicit conversions.

Candidate functions

Call to a named function

Call to a class object

Call to an overloaded operator

Initialization by constructor

Copy-initialization by conversion

Non-class initialization by conversion

Reference initialization by conversion

List-initialization

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:

1) If there are M arguments, the candidate function that has exactly M parameters is viable
2) If the candidate function has less than M parameters, but has an ellipsis parameter (is a variadic function), it is viable.
3) If the candidate function has more than 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.
4) For every argument there must be at least one implicit conversion sequence that converts it to the corresponding parameter.
5) If any parameter has reference type, reference binding is accounted for at this step: if an rvalue argument corresponds to non-const lvalue reference parameter or an lvalue argument corresponds to rvalue reference parameter, the function is not viable.

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

1) there is at least one argument of F1 whose implicit conversion is better' than the corresponding implicit conversion for that argument of F2
2) or. if not that, (only in context of non-class initialization by conversion), the standard conversion sequence from the return type of F1 to the type being initialized is better than the standard conversion sequence from the return type of F2
3) or, if not that, F1 is a non-template function while F2 is a template specialization
4) or, if not that, F1 and F2 are both template specializations and F1 is ``more specialized`` according to the partial ordering rules for template specializations

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
}

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:

1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base

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 to a reference parameter directly to the argument expression is either Identity or a derived-to-base Conversion:

struct Base {};
struct Derived : Base {} b;
int f(A&); // overload #1
int f(B&); // overload #2
int i = f(b); // b -> B& has rank Exact Match
              // b -> A& has rank Conversion
              // calls f(B&)

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.

1) A standard conversion sequence is always better than a user-defined conversion sequence or an ellipsis conversion sequence.
2) A user-defined conversion sequence is always better' than an ellipsis conversion sequence
3) A standard conversion sequence S1 is better' thank a standard conversion sequence S2 if
a) S1 is a subsequence of S2, excluding lvalue transformations. The identity conversion sequence is considered a subsequence of any other conversion
b) Or, if not that, the rank of S1 is better thank the rank of S2
c) Or, if their ranks are the same, but they only differ in qualification conversion, and the cv-qualification of the result of 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*)
d) or, if not that, both 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&
e) or, if not that, both 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.
f) or, if not that, both 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
4) A user-defined conversion sequence U1 is better than a user-defined conversion sequence U2 if they call the same constructor/user-defined conversion function and 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)
5) A list-initialization sequence 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:

1) Conversion that involves pointer-to-bool, pointer-to-member to bool, or std::nullptr_t to bool conversion is worse than the one that doesn't
2) Conversion that converts pointer-to-derived to pointer-to-base is better than the conversion of pointer-to-derived to pointer-to-void, and conversion of pointer-to-base to void is better than pointer-to-derived to void.
3) If Mid is derived (directly or indirectly) from Base, and Derived is derived (directly or indirectly) from Mid
a) Derived* to Mid* is better than Derived* to Base*
b) Derived to Mid& is better than Derived to Base&
c) Base::* to Mid::* is better than Base::* to Derived::*
d) Derived to Mid is better than Derived to Base
e) Mid* to Base* is better than Derived* to Base*
f) Mid to Base& is better than Derived to Base&
g) Mid::* to Derived::* is better than Base::* to Derived::*
h) Mid to Base is better than Derived to Base

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

See also