[try Beta version]
Not logged in

 
overloaded function declarations

Apr 10, 2019 at 2:12pm
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 Apr 14, 2019 at 3:38am
Apr 10, 2019 at 2:35pm
If you were the compiler, which function would you make a call to when seeing foo(5, 6)?
Last edited on Apr 10, 2019 at 2:35pm
Apr 10, 2019 at 2:53pm
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
Apr 10, 2019 at 2:58pm
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 
Apr 10, 2019 at 4:18pm
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

Apr 10, 2019 at 4:38pm
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...
Apr 10, 2019 at 8:20pm
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.