0

Let's see the following function overloading declaration

void funA(int);
void funA(float);

Then we call the function like this:

funA(1);          // this will be ok.

however,

funA(1.333)         // this will not ok..

To the compiler, funA(int) and funA(float) will be ambiguous.. The compiler will cast 1.333 value to integer (1) .. although assuming it's a float value would be more appropriate..

I'm using g++ (GCC) 4.8.2 Why the compiler will not call funA(float) instead? The following works however..

funA(static_cast<float>(1.333))
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
Ari
  • 92
  • 5

1 Answers1

5

The literal 1.333 is a double, not a float. The conversion from double to int is considered to be as good as that of double to float, so resulting in the ambiguous overload error. To disambiguate, pass a float:

funA(1.333f);

If you wanted to be sure to dispatch calls with double arguments to funA(float), then you can follow @JamesKanze's example from the comments:

void funA( double v ) 
{ 
  return funA( static_cast<float>( v ) );
}

but note that the range of a double is likely to be greater than that of a float.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 2
    He violated a general rule concerning overloading: if you overload for any integral type (except maybe `char`), then overload for `int` as well; if you overload for any floating point type, then overload for `double` as well. For the reason the OP has just discovered. (You might add the suggestion that he add `funA( double v ) { funA( static_cast( v ) ); }` to the set of overloaded functions.) – James Kanze May 15 '14 at 12:46
  • Hi, thank you for your answer.. Ok, literal like 1.3333 is automatically assumed as double and not float.. But still, why the compiler choose to use overloaded function with double, even when overloaded function with double is not defined? You mention conversion from double to int is considered to be as good as that of double to float.. why is that? – Ari May 15 '14 at 13:03
  • 1
    @Ari The compiler doesn't cast anything as double. A literal such as `1.23` is defined to be `double` in the language, just like `42` is an `int`. As for the conversions to other numeric types, those are the rules of the language. I can only speculate that it is this way because it is a simpler rule to enforce and remember. – juanchopanza May 15 '14 at 13:06
  • 1
    Thank you. I try to summarize. - compiler always defines a literal like 3.22 as double. - if this literal is feed to a function, if the function that takes double is not found, the compiler will use an available version that may take int, float, or(?) and will cast the literal to int or to float - if both version present, the compiler won't prefer the float version to int version, although it may look more appropriate(?) - casting will change the literal representation whether it is casting from double to int or from double to float, so they both are as good to the compiler. – Ari May 15 '14 at 13:34
  • @Ari Yes, that sounds right! – juanchopanza May 15 '14 at 13:36