Open In App

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

Last Updated : 29 Dec, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

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 <iostream>
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 <iostream>
    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 <iostream>
    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 <iostream>
    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 <iostream>
    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
    


Similar Reads

What are the Operators that Can be and Cannot be Overloaded in C++?
There are various ways to overload Operators in C++ by implementing any of the following types of functions: 1) Member Function 2) Non-Member Function 3) Friend Function List of operators that can be overloaded are: + - * ? % ? &amp; | ~ ! = &lt; &gt; += -= *= ?= %= ?= &amp;= |= &lt;&lt; &gt;&gt; &lt;&lt;= &gt;&gt;= == != &lt;= &gt;= &amp;&amp; ||
4 min read
error: call of overloaded ‘function(x)’ is ambiguous | Ambiguity in Function overloading in C++
Pre-requisite: Function Overloading in C++ Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading. Two or more functions are said to be overloaded if they differ in any of th
9 min read
Functions that cannot be overloaded in C++
In C++, following function declarations cannot be overloaded. 1) Function declarations that differ only in the return type. For example, the following program fails in compilation. C/C++ Code #include&amp;lt;iostream&amp;gt; int foo() { return 10; } char foo() { return 'a'; } int main() { char x = foo(); getchar(); return 0; } 2) Member function de
3 min read
Hiding of all Overloaded Methods with Same Name in Base Class in C++
In C++, function overloading is possible i.e., two or more functions from the same class can have the same name but different parameters. However, if a derived class redefines the base class member method then all the base class methods with the same name become hidden in the derived class. For example, the following program doesn't compile. Here,
3 min read
Can main() be overloaded in C++?
Predict the output of following C++ program. #include &lt;iostream&gt; using namespace std; int main(int a) { cout &lt;&lt; a &lt;&lt; &quot;\n&quot;; return 0; } int main(char *a) { cout &lt;&lt; a &lt;&lt; endl; return 0; } int main(int a, int b) { cout &lt;&lt; a &lt;&lt; &quot; &quot; &lt;&lt; b; return 0; } int main() { main(3); main(&quot;C++
2 min read
C/C++ program for calling main() in main()
Given a number N, the task is to write C/C++ program to print the number from N to 1 by calling the main() function using recursion.Examples: Input: N = 10 Output: 10 9 8 7 6 5 4 3 2 1Input: N = 5 Output: 5 4 3 2 1 Approach: Use static variable to initialise the given number N.Print the number N and decrement it.Call the main() function recursively
2 min read
Calling a non-member function inside a class in C++
Member Function: It is a function that can be declared as members of a class. It is usually declared inside the class definition and works on data members of the same class. It can have access to private, public, and protected data members of the same class. This function is declared as shown below: C/C++ Code // Given Class class memberdemo { priv
3 min read
Calling Conventions in C/C++
In C/C++ programming, a calling convention is a set of rules that specify how a function will be called. You might have seen keywords like __cdecl or __stdcall when you get linking errors. For example: error LNK2019: unresolved external symbol "void __cdecl A(void)" (?A@@YAXXZ) referenced in function _mainHere, we see __cdecl being used. It is one
11 min read
Calling virtual methods in constructor/destructor in C++
Prerequisite: Virtual Function in C++Calling virtual functions from a constructor or destructor is considered dangerous most of the times and must be avoided whenever possible. All the C++ implementations need to call the version of the function defined at the level of the hierarchy in the current constructor and not further. You can call a virtual
2 min read
Program to find all match of a regex in a string
Prerequisite: smatch | Regex (Regular Expressions) in C++ Given a regex, the task is to find all regex matches in a string. Without using iterator: Implementation: C/C++ Code // C++ program to find all the matches #include &lt;bits/stdc++.h&gt; using namespace std; int main() { string subject(&quot;My GeeksforGeeks is my &quot; &quot;GeeksforGeeks
5 min read