M. Alduino M. Alduino - 1 month ago 12
C++ Question

Ambiguous function overload in C++

I am following right now a C++ coursera-course, trying to compile example from here: Ira Pohl’s C++ by Dissection with both g++ and intel's c++ compilers.

got some errors with both compilers, like this on every call to greater:

rational.cpp(69): error: "greater" is ambiguous
<< greater(i, j);
^



/***************************************************************
* C++ by Dissection By Ira Pohl Addison Wesley
* Chapter 5 Ctors, Dtors, Conversion, and Operator Overloading
* Compiled with Borland C++ Builder Version 5.0 Summer 2001
******************************************************************/

//Overloading functions

#include <iostream>
using namespace std;


// Overloading functions

class rational {
public:
rational(int n = 0) : a(n), q(1) { }
rational(int i, int j) : a(i), q(j) { }
rational(double r) : a(static_cast<long>
(r * BIG)), q(BIG) { }
void print() const { cout << a << " / " << q; }
operator double()
{ return static_cast<double>(a) / q; }
friend ostream& operator<<(ostream& out, const rational& x);
friend istream& operator>>(istream& in, rational& x);
friend bool operator>(rational w, rational z);
private:
long a, q;
enum { BIG = 100 };
};



ostream& operator<<(ostream& out, const rational& x)
{
return (out << x.a << " / " << x.q << '\t');
}

istream& operator>>(istream& in, rational& x)
{
return (in >> x.a >> x.q);
}


bool operator>(rational w, rational z)
{
return (static_cast<double>(w.a) / w.q > static_cast<double>(z.a) / z.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();
cout << endl;
}

Answer

The greater function is present in the imported std namespace as well as the source file, so the compiler can't decide which one should be used.

Maybe this wasn't the case with Borland C++ 5.0, so the code compiled fine back then. This is a nice example why using namespace std is usually a bad idea.

You might try to remove that declaration and manually add an explicit std:: prefix where needed (the compiler will tell you).