Calling of overloaded subroutines and ways for finding accurate match in C++

• Last Updated : 29 Dec, 2020

Just like other subroutines, overloaded subroutines are also called. To decide which function to invoke it is important to determine the number and type of arguments. For example, the below part of code will tell about the calling overloading subroutine:

```prnsqr('z')                   // calls #2
prnsqr(13)                    // calls #1
prnsqr(134.520000012)         // calls #4
prnsqr(12.5F)                 // calls #3
```

The appropriate function is called for execution when the function call initially matches the prototype available along with the digit and type of arguments given.

Between the float, double values, or int or long values, there can be an ambiguity like the function invoked by the following declaration:

`void prnsqr(double d);`

With a 1.24 value, can assume to be float or double. The constant suffixes(F, U, L, UL), etc. are used to avoid ambiguity these values help in demonstrating which overloading subroutine to be called. The ordinary floating constant (312.32) is a double type, the F suffix (312.32 F) is a float type, L (312.32 L) makes its long double. For integers, a constant without a suffix is the signed int value. U suffix is unsigned constant & L suffix is long, LU or UL is unsigned long. These suffixes can be written in lower or uppercase letters.

Below is the implementation of the above approach:

C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;`` ` `class` `Distance {``private``:``    ``int` `centimeter;``    ``int` `kilometer;`` ` `public``:``    ``// Default Constructors``    ``Distance()``    ``{``        ``centimeter = 0;``        ``kilometer = 0;``    ``}`` ` `    ``// Parameterized Constructors``    ``Distance(``int` `cm, ``int` `km)``    ``{``        ``centimeter = cm;``        ``kilometer = km;``    ``}`` ` `    ``// Overload function call``    ``Distance operator()(``int` `a,``                        ``int` `b, ``int` `c)``    ``{``        ``Distance D;``        ``D.centimeter = a + c + 10;``        ``D.kilometer = b + c + 100;``        ``return` `D;``    ``}`` ` `    ``// To display distance``    ``void` `displayDistance()``    ``{``        ``cout << ``"centimeter: "``             ``<< centimeter``             ``<< ``"kilometer:"``             ``<< kilometer << ``'\n'``;``    ``}``};`` ` `// Driver Code``int` `main()``{``    ``Distance D1(87, 33), D2;`` ` `    ``cout << ``"First Distance : "``;``    ``D1.displayDistance();`` ` `    ``// Invoke operator()``    ``D2 = D1(10, 10, 10);``    ``cout << ``"Second Distance :"``;`` ` `    ``D2.displayDistance();`` ` `    ``return` `0;``}`

Output:

```First Distance : centimeter: 87kilometer:33
Second Distance :centimeter: 30kilometer:120
```

Ways To Find Accurate Match:

The call is resolved for an overloaded subroutine by an instance of function through a process called Argument Matching also termed as the process of disambiguation. Below are the 3 cases that can be possible, the function call may result:

1. Match: found for function call.
2. No Match: for function call.
3. Ambiguous Match: more than one described instance match.

The compiler will try to find the best match for the function call.

Steps Taken By Compiler For Matching

• Searching for an exact match: When the actual argument type matches exactly with the type of one defined instance, the compiler will invoke for that instance. For Examples:
```// For overloaded functions
void afunc(int);
void afunc(double);

// For exact match. Match afunc(int)
afunc(0);
```

0(zero) is int type, matches afunc(int) with call.

Below is the program for the same:

C++

 `// C++ program for the above approach`` ` `#include ``using` `namespace` `std;`` ` `// Function for integer parameter``void` `afunc(``int` `h)``{``    ``cout << ``"Integer:"` `<< h;``}`` ` `// Function for double parameter``void` `afunc(``double` `d)``{``    ``cout << ``"double:"` `<< d;``}`` ` `// Driver code``int` `main()``{``    ``afunc(0);``    ``return` `0;``}`

Output:

```Integer:0
```
• Match through promotion: The compiler will make an attempt to get a match through the promotion of the actual argument if no exact match found. If all values cannot be represented by int and the conversion of integer types into (char, short, enumerator, int), or to unsigned int is called integral promotion. Now we will see the following code part:

void afunc(int)
void afunc(float)

// For match through promotion
afunc(‘c’)

where, ‘c’ is the type char and promoted to INT type as no exact match found.

Below is the program for the same:

C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;`` ` `// Function for integer parameter``void` `value(``int` `s)``{``    ``cout << ``"Integer:"` `<< s;``}`` ` `// Function for character parameter``void` `value(``char``* b)``{``    ``cout << ``"Char:"` `<< b;``}`` ` `// Driver Code``int` `main()``{``    ``char` `st = ``'d'``;``    ``value(st);``    ``return` `0;``}`

Output:

```Integer:100
```
• Through the application of the standard C++ conversion rule found a match: An attempt is made to achieve a match through a standard conversion of the actual argument if no exact match or match through a promotion is found. Below is the example for the same:

void afunc(char)
void afunc(double)

// For match through std conversion
afunc(471)
match a func(double)

Using C++ standard conversion rules the int argument 471 can be converted to a double value 471 and if the actual argument may be converted to multiple formal argument types compiler will generate an error message as it is an ambiguous match. For Example:

```void afunc(long)
void afunc(double)

// Error will generate as ambiguous match
afunc(15)
```

The int argument 15 converted to long or double generating an ambiguous circumstance as to which afunc() be used.

Below is the program for the same:

C++

 `// C++ program to explain the standard``// conversion rule``#include ``using` `namespace` `std;`` ` `// Driver Code``int` `main()``{``    ``// integer h``    ``int` `h = 11;`` ` `    ``// character c``    ``char` `s = ``'a'``;`` ` `    ``// s implicitly converted``    ``// to int. ASCII value of``    ``// 'a' is 97``    ``h = h + s;`` ` `    ``// h is implicitly converted``    ``// to float``    ``float` `f = h + 1.0;`` ` `    ``cout << ``"h = "` `<< h << endl``         ``<< ``"s = "` `<< s << endl``         ``<< ``"f = "` `<< f << endl;`` ` `    ``return` `0;``}`

Output:

```h = 108
s = a
f = 109
```

Note: If no promotion is seen then the compiler finds a match through standard conversion. Any numeric type is matched with another numeric type including unsigned (say int and float). Enum is going to match with the formal type of numeric type ( e.g. enum to float). 0 has to be matched a pointer type and numeric type (say 0 to char*, 0 to float). Though Pointer matched by a void pointer.

• Through the application of a user define conversion find a match: Now the compiler will use a user-defined conversion in combination with integral promotion and built-in conversions to find a unique match if all the above steps will fail. Any function whether it is a class member or just a normal function can be overloaded in C++ given is needed to work for different argument types numbers and combinations.

Below is the program for the same:

C++

 `// C++ program to illustrate the user``// defined type casting``#include ``using` `namespace` `std;`` ` `// Driver Code``int` `main()``{``    ``double` `h = 1.4;`` ` `    ``// Explicit conversion``    ``// from double to int``    ``int` `add = (``int``)h + 2;`` ` `    ``cout << ``"Add = "` `<< add;``    ``return` `0;``}`

Output:

```Add = 3
```

My Personal Notes arrow_drop_up