Ad Hoc Polymorphism  «Prev 

Overload Function Selection Algorithm Example in C++


//Overloading functions
const int BIG = 100;
class rational{
public:
   rational(int n = 0) : a(n),q(1){}
   rational(int i, int j) : a(i), q(j){}
   rational(double r) : q(BIG), a(r * BIG){}
   void  print() const { cout << a << " / " << q ; }
   operator double() { return static_cast<double>(a)/q; }
private:
   long  a, q;
};

inline int     greater(int i, int j){ 
 return ( i > j ? i : j); 
}
inline double  greater(double x, double y){ 
 return ( x > y ? x : y); 
}
inline rational greater(rational w, rational z) { 
 return ( w > z ? w : z); 
}

int main(){
   int      i = 10, j = 5;
   float    x = 7.0;
   double   y = 14.5;
   rational w(10), z(3.5), zmax;
    
   cout << "\ngreater(" << i << ", " << j << ") = "
     << greater(i, j);
   cout << "\ngreater(" << x << ", " << y << ") = "
     << greater(x, y);
   cout << "\ngreater(" << i << ", " ;
   z.print();
   cout << ") = " << greater(static_cast<rational>(i), z);
   zmax = greater(w, z);
   cout << "\ngreater(";
   w.print();
   cout << ", ";
   z.print();
   cout << ") = ";
   zmax.print();
}

rational(double r) : q(BIG), a(r * BIG){}

This constructor converts from double to rational .
operator double(){ return static_cast<double>(a)/q; }

This member function converts from rational to double.
inline int     greater(int i, int j)
      { return ( i > j ? i : j); }
inline double  greater(double x, double y)
      { return ( x > y ? x : y); }
inline rational greater(rational w, rational z)
      { return ( w > z ? w : z); }

Three distinct functions are overloaded. The most interesting has rational type for its argument list variables and its return type. The conversion member function operator double is required to evaluate w > z. Later, we'll show how to overload operator>() to take rational types directly.

cout << "\ngreater(" << i << ", " << j << ") = "
<< greater(i, j);
cout << "\ngreater(" << x << ", " << y << ") = "
<< greater(x, y);

The first statement selects the first definition of greater because of the exact match rule. The second statement selects the second definition of greater because of the use of a standard promotion conversion float to double. The value of variable x is promoted to double.

<< greater(static_cast<rational>(i), z);

The third definition of greater is selected because the required cast coerces i to be type rational. The explicit conversion of i to a rational is necessary to avoid ambiguity. The function call greater(i, z) would have to have two available conversions to achieve a match. The user-defined conversion of int to rational for the argument i matches the third definition. The user-defined conversion from rational to double for the argument z matches the second definition. This violates the uniqueness provision for matching when user-specified conversions are involved. This is an exact match for definition three.

zmax = greater(w, z);