overloaded function declarations

Can someone explain to me why is foo(5,6) wrong and why the rest are correct? I don't understand. Thanks.

1
2
3
4
5
6
7
8
9
10
11
Given the following overloaded function declarations:
void foo(int a, int b = 10, float c = 0.0f);
void foo(int a, float b = 3.14f);

Check function calls that are not compilable.   

foo(5, 6); compilable
  
foo(8); not compilable
  
foo(7, 2, 8); compilable
Last edited on
If you were the compiler, which function would you make a call to when seeing foo(5, 6)?
Last edited on
foo(5, 6)
6 is an integer, it would call the one that ask for an integer as its second parameter

foo(8) is ambiguous
Overload resolution is quite complex:
https://en.cppreference.com/w/cpp/language/overload_resolution

If your code requires anything complex, I suggest that you add a comment saying which function gets called.

I'm confused by your example too but for a different reason. Maybe someone else can set us both straight. By my thinking:

1
2
3
foo(5, 6);    // Wrong. foo(int,int,float) and foo(int,float) are both viable
foo(8);       // Seems wrong to me for the same reason as above.
foo(7, 2, 8); // Correct. Only foo(int,int,float) has 3 arguments 
I’ve asked the compiler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>

void foo(int a, int b = 10, float c = 0.0f);
void foo(int a, float b = 3.14f);


int main()
{
    std::cout << "Invoking foo(5, 6): ";
    foo(5, 6);

    std::cout << "\nInvoking foo(8): ";
    foo(8);
  
    std::cout << "\nInvoking foo(7, 2, 8);: ";
    foo(7, 2, 8);
}


void foo(int a, int b, float c)
{
    std::cout << " --> I'm foo(int a, int b = 10, float c = 0.0f):\n"
                 " --> a: " << a << "; b: " << b << "; c: " << c << '\n';
}


void foo(int a, float b)
{
    std::cout << " --> I'm void foo(int a, float b = 3.14f):\n"
                 " --> a: " << a << "; b: " << b << '\n';
}


Output:
main.cpp: In function 'int main()':
main.cpp:13:10: error: call of overloaded 'foo(int)' is ambiguous
     foo(8);
          ^
main.cpp:3:6: note: candidate: 'void foo(int, int, float)'
 void foo(int a, int b = 10, float c = 0.0f);
      ^~~
main.cpp:4:6: note: candidate: 'void foo(int, float)'
 void foo(int a, float b = 3.14f);
      ^~~


- - -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>

void foo(int a, int b = 10, float c = 0.0f);
void foo(int a, float b = 3.14f);


int main()
{
    std::cout << "Invoking foo(5, 6): ";
    foo(5, 6);

    // std::cout << "\nInvoking foo(8): ";
    // foo(8);
  
    std::cout << "\nInvoking foo(7, 2, 8);: ";
    foo(7, 2, 8);
}


void foo(int a, int b, float c)
{
    std::cout << " --> I'm foo(int a, int b = 10, float c = 0.0f):\n"
                 " --> a: " << a << "; b: " << b << "; c: " << c << '\n';
}


void foo(int a, float b)
{
    std::cout << " --> I'm void foo(int a, float b = 3.14f):\n"
                 " --> a: " << a << "; b: " << b << '\n';
}


Output:
Invoking foo(5, 6):  --> I'm foo(int a, int b = 10, float c = 0.0f):
 --> a: 5; b: 6; c: 0

Invoking foo(7, 2, 8);:  --> I'm foo(int a, int b = 10, float c = 0.0f):
 --> a: 7; b: 2; c: 8

I recommend not making overloads where common automatic type conversions can be misunderstood. Its possible to do it and get it right, but the next user of the code may struggle with it, and it is easy to call the wrong version and not know it in some cases, as shown here.

There are many ways to avoid this problem, if that turns out to be the best way...
Okay, so it looks like foo(5,6) works because it matches foo(int a, int b=10, float c=0.0f) without needed to convert either of the arguments. To call foo(int, float) it would have to convert 6 to a float.

From the link I posted above:
Best viable function
...
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
Topic archived. No new replies allowed.