1

I'm learning C++ through Sololearn. I have a doubt about function overloading

this is the code

#include<iostream>
using namespace std;


void printSomething(int x)   {

   cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x)   {

   cout << "I'm printing a float " << x << endl;
}

int main()  {

   int a =3; 
   float b = 2.65;
   printSomething(a);
   printSomething(b);
   return 0;
}

it gives output as

               I'm printing an integer 3 
               I'm printing a float 2.65

but if I directly give argument when calling function

like this

#include<iostream>
using namespace std;


void printSomething(int x)   {

   cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x)   {

   cout << "I'm printing a float " << x << endl;
}

int main()  {

   printSomething(3);
   printSomething(2.65);
   return 0;
}

i get following error

..\Playground: In function 'int main()': ..\Playground:19:24: error: call of overloaded 'printSomething(double)' is ambiguous printSomething(2.65); ^ ..\Playground:19:24: note: candidates are: ..\Playground:5:6: note: void printSomething(int) void printSomething(int x) { ^ ..\Playground:9:6: note: void printSomething(float) void printSomething(float x) { ^

but if I change

void printSomething(float x)   {

    cout << "I'm printing a float " << x << endl;
}

to

void printSomething(double x)   {

    cout << "I'm printing a float " << x << endl;
}

I will get output as

       I'm printing a float 2.65

why is it? but if it's only the integer it works fine

#include<iostream>
using namespace std;


void printSomething(int x)   {

   cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x)   {

   cout << "I'm printing a float " << x << endl;
}

int main()  {

    printSomething(3);
    return 0;
}

Result

                      I'm printing an integer 3

Why isn't this working with float

Thankyou

Athul
  • 429
  • 2
  • 5
  • 19

3 Answers3

4

2.65 is not a float literal, it's a double literal.

So the compiler doesn't know whether you want to convert the double to a float or an int and so issues the error.

In your first case, when writing float b = 2.65; the compiler assumes you know what you're doing, and calling the overload with b is unambiguous.

If you had written printSomething(2.65f); then that would also have been unambiguous: 2.65f is a float literal.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

2.65 is considered a double. But you didn't provide an overload void printSomething(double x). Therefore the compiler must cast the value and it doesn't know if it should cast to float or int (both with precision loss`).

If you write 2.65f it is considered a float and it should work.

max
  • 198
  • 8
0

The reason for that is the conversion rules and overload resolution strategy. If C++ is unable to find an exact match on parameters, it looks for a conversion. The best conversion is an implicit one, that is widening (casting a data type to one that can hold all the values of the original type and potentially more), then a narrowing conversion (casting to a smaller data type, which may cause errors or loss of precision for some values), then a user-defined conversion.

As literal 2.65 is of type double, the compiler looks for conversions. There are two: double -> float and double -> int. They are both narrowing, which means they are equally good. The compiler is unable to pick the best one, thus reports an error.

To remedy this, you can either:

  • define overload for double as you did
  • use a float literal (2.65f) instead of a double
majk
  • 827
  • 5
  • 12