1

As we know when we do function overloading in template function with ordinary function, If the compiler get the exact match with ordinary fun() it will call ordinary fun() and ignore the template fun(). But in the below C++ code when I run the code it call the template function not ordinary function. Why?

Code

#include<iostream>
using namespace std;

template<class T1, class T2>
void fun(T1 x, T2 y){
    cout << "TEMPLATE FUNCTION : " << x << " | " << y << endl;
}

void fun(int a, float b){
    cout << "ORDINARY FUNCTION : " << a << " | " << b << endl;
}

int main(){
    fun(3, 4.7);
    return 0;
}

Output

TEMPLATE FUNCTION : 3 | 4.7
Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
the_razz03
  • 77
  • 1
  • 4
  • 8
    Because 4.7 is double, not float. – 273K Jan 22 '21 at 18:30
  • 2
    Try calling `fun(3, 4.7f)` (note the `f` suffix for the floating point value). – Some programmer dude Jan 22 '21 at 18:32
  • 1
    I see this question already has 2 close votes for Typo. I don't see how a misunderstanding of the details of overload resolution counts as a typo. – cigien Jan 22 '21 at 18:37
  • 2
    @S.M. Please do not answer in the comments section. You should know how this site works by now! – Asteroids With Wings Jan 22 '21 at 18:39
  • 1
    @cigien It's not a misunderstanding of the details of overload resolution. It's a misunderstanding of the type of the literal `4.7`, which is deemed _trivial_, and "typo" is the closest thing we have to trivial as a close reason, so it's commonly used as such. ‍♂️ – Asteroids With Wings Jan 22 '21 at 18:40
  • @AsteroidsWithWings Oh, I see. I'm still unhappy about closing for that reason. Triviality is a fairly subjective thing, and we don't have a *too simple* close reason partly for that reason. – cigien Jan 22 '21 at 18:42
  • @cigien That's fine - nobody's making you cast that vote :) – Asteroids With Wings Jan 22 '21 at 18:48
  • @AsteroidsWithWings Well, of course no one is forcing me to cast a close vote :) I can still voice my objections to what I see as incorrect close votes being cast. – cigien Jan 22 '21 at 18:51
  • 2
    @AsteroidsWithWings: What does closeness have to do with it? “Close to correct” is not correct. Two things can be very near each other and yet very different. A typo is distinctly different from a misunderstanding of the type of a literal, as a typo is a mechanical error that a person will recognize when they see it, whereas a person who does not understand the issues about types of literals will not recognize it when they see it. Therefore answers are not needed to explain typos, but answers are needed to explain type issues. – Eric Postpischil Jan 22 '21 at 19:04
  • @EricPostpischil I'm not claiming otherwise, I'm just explaining to cigien why some people vote that way. If you have a problem with them doing so, feel free to talk to them about it, preferably on meta. – Asteroids With Wings Jan 22 '21 at 19:25
  • Potential duplicate: [int and float in function overloading](https://stackoverflow.com/questions/34208397/int-and-float-in-function-overloading/34208458#34208458). Same principle, but different presentation. *(Unfortunately if I were to try to officially suggest a duplicate, it would be a third close vote and the "typo" votes would outnumber the "duplicate" vote. I disagree with closing as a typo, so I'll refrain for now.)* – JaMiT Jan 22 '21 at 19:33

2 Answers2

4

In this call:

fun(3, 4.7);

the second argument 4.7 is a double. As you mentioned in your question, the non-template function is called only if the arguments are an exact match. Since the non-template function expects a float for the second argument, this requires a conversion from double to float. This is not an exact match, and so the template is selected.

If you want the non-template to be selected, then pass a float as the second argument:

fun(3, 4.7f);
cigien
  • 57,834
  • 11
  • 73
  • 112
  • @RajVardhanUpreti It's not stupid at all. It's not an obvious thing, and everyone gets things wrong sometimes :) – cigien Jan 22 '21 at 18:47
2

Template functions are generic in this case, practically meaning they can accept more than one predefined data type. Since your parameter for fun includes a double, it defaults to template function fun. Once you change the parameter to float it should call the ordinary function correctly.

yaozhang
  • 69
  • 7