template <typename T>
inline T const& max (T const& a, T const& b)
{
// if a < b then use b else use a
return a<b?b:a;
}
// In this example we have to explicitly specify the
// return type as the parameters are diff type
template <typename T1, typename T2>
inline T1 max2 (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
// you can introduce a third template argument type to
// define the return type of a function template
template <typename RT, typename T1, typename T2>
inline RT max3 (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
// Function overloading
// maximum of two int values (non-template)
inline int const& max (int const& a, int const& b)
{
return a<b?b:a;
}
// Function overloading
// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c);
}
int main()
{
int i = 42;
std::cout << "max(7,i): " << ::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;
std::string s1 = "mathematics";
std::string s2 = "math";
std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
//std::complex<float> c1, c2; // doesn't provide operator <
//::max(c1,c2); // ERROR at compile time
//max(4,4.2) // ERROR: first T is int, second T is double
max(static_cast<double>(4),4.2);
max<double>(4,4.2);
// Another option :- Specify the parameters have diff types
max2(4,4.2); // OK, but type of first argument defines return type
max3<int,double,double>(4,4.2); // OK, but tedious
max3<double>(4,4.2); // OK: return type is double, T1 is int and T2 is double
::max(7, 42, 68); // calls the template for three arguments
::max(7.0, 42.0); // calls max<double> (by argument deduction)
::max('a', 'b'); // calls max<char> (by argument deduction)
::max(7, 42); // calls the nontemplate for two ints
::max<>(7, 42); // calls max<int> (by argument deduction)
::max<double>(7, 42); // calls max<double> (no argument deduction)
::max('a', 42.7); // calls the nontemplate for two ints
}