c++language-lawyeroverload-resolutiondefault-arguments

Are default argument conversions considered in overload resolution?


Consider the following code:

void foo(int* = 0); // (1)
void foo(int  = 0); // (2)

int main() {
    foo(0); // OK, calls (2)
    foo();  // error, ambiguous overload
}

Both GCC and clang act like this, but I'm not convinced that it's correct.

[expr.call] p6 merely says:

If there is no corresponding argument, the default argument for the parameter is used.

This suggests that once a function call is made, foo will turn into foo(0) and that 0 will have to be converted to int* for (1).

Therefore, I believe both function calls should be valid. However, is there wording which contradicts this idea? Are conversions of default arguments considered to be "free" so that they don't contribute to the conversion sequence?


Solution

  • Before we can consider something a "function call", the postfix-expression (the identifier before ()) must be resolved from possible overloads (if it's a function name and not e.g. an object). See Note 1 in [expr.call]:

    [Note 1: If the postfix expression is a function or member function name, the appropriate function and the validity of the call are determined according to the rules in [over.match]. — end note]

    And when doing overload resolution, we have the following in [over.match.viable] (emphasis mine):

    First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list.

    (2.1) If there are m arguments in the list, all candidate functions having exactly m parameters are viable.
    [...]
    (2.3) A candidate function having more than m parameters is viable only if all parameters following the mth have default arguments ([dcl.fct.default]).
    For the purposes of overload resolution, the parameter list is truncated on the right, so that there are exactly m parameters.

    Your function call has 0 arguments, and both overloads of foo have 1 default parameter. This falls into 2.3 - the default parameters are truncated from the parameters lists of both candidate functions, and so we end up with 2 viable functions, both with 0 parameters, indistinguishable from each other.