The reason it's ambiguous is because you have two separate functions. One resides in the maths
namespace, and is declared by the one marked friend
inside the class. This one can be found through Argument Dependent Lookup. You also have a full definition outside of the namespace. Both of these are equally valid.
To start, it's not accessing any private members of the class, so the friend
declaration isn't needed. Simply don't make it a friend, as that just hurts encapsulation.
Secondly, I suggest moving the definition into the maths
namespace because it belongs in there alongside the class it's operating on. As said before, ADL will still find it because the second argument is of a type in that namespace, so the namespace is searched and the overload found.
All in all, you should end up with this:
namespace maths {
class complex_number{
public:
// lots of functions and two variables
};
std::istream& operator >>(std::istream &in, maths::complex_number &input)
{
std::cout << "Please enter the real part of the number > ";
in >> input.a;
std::cout << "Please enter the imaginary part of the number > ";
in >> input.b;
return in;
}
}
int main(int argc, char **argv)
{
maths::complex_number b;
std::cin >> b; //operator>> found by ADL
return 0;
}
One final note is the overload itself. Input really shouldn't prompt for inputs, it should just read them. This way, you can use it with the keyboard, a file, or whatever other derivative of std::istream
is desired.