Namespaces
Variants
Views
Actions

Overload resolution

From cppreference.com
< cpp‎ | language
Revision as of 20:57, 20 June 2013 by Cubbi (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 

In order to compile a function call expression, 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 candidate 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 functions (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-qualification sof 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


See also