I have a class using operator overloading, but there are some warnings.
// base.h
class base {
public:
base();
base(int n);
virtual ~base();
virtual void printBase(std::ofstream & out);
virtual base & operator =(const base &);
friend std::ofstream & operator <<(std::ofstream & out, const base &);
private:
double * coeff;
int n;
};
// base.cpp
std::ofstream & operator<<(std::ofstream & fout, const base & obj)
{
for(int i =0; i<(obj.n)-1; i++)
{
fout << obj.coeff[i]<<"*x"<<i;
if(i<obj.n-2)
{
fout<<"+";
}
}
fout<<"="<<obj.coeff[(obj.n)-1];
return fout;
}
void base::printBase(std::ofstream & fout)
{
for(int i =0; i<n-1; i++)
{
fout<<coeff[i]; // warning occurs here!!
if(i<n-2)
{
fout<<"+";
}
}
fout<<"="<<coeff[n-1];
}
The warning is:
>
warning: ISO C++ says that these are ambiguous, even though the worst conversion for
the first is better than the worst conversion for the second:
c:\wascana\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/ostream.tcc:105:5: note:
candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
..\Hyperplane.cpp:55:17: note: candidate 2: std::ofstream& operator<<(std::ofstream&, const Hyperplane&)
From the above warning, it should be the problem of <<. I know the reason, but how could I handle this warning?
Thank you!
The problem is actually with one of your class's constructors:
base(int n);
This constructor is what is called a converting constructor. It can be used to convert an int to a base, so this would be legal:
base x = 42;
If you don't want to allow this implicit conversion, you can make the constructor explicit:
explicit base(int n);
The interesting question is "where is the ambiguity in fout << coeff[i];?
There are two candidate functions that the compiler can't decide between (or shouldn't be able to decide between; your compiler is being "nice" to you): one is the built-in std::ostream operator<< overload that looks like this:
std::ostream& operator<<(std::ostream&, double);
the second is your operator overload that looks like:
std::ofstream& operator<<(std::ofstream&, const base&);
With the first candidate, the first argument requires a derived-to-base conversion: the std::ofstream needs to be converted to a std::ostream for the function to be called. The second argument, a double, matches exactly.
With the second candidate, the first argument, a std::ofstream, matches exactly. The second argument requires the use of the built-in double to int conversion then the use of your converting constructor to convert from int to base.
In order for the compiler to select one candidate function as the right one to call, each of the arguments must match the corresponding parameter of the candidate at least as well as it matches any of the other candidates.
With these two candidates here, the first argument matches the second candidate better but the second argument matches the first candidate better, thus there is an ambiguity.
An alternative solution would be to change your overload such that the first argument matches as well as the first argument of the built-in candidate:
std::ostream& operator<<(std::ostream&, const base&);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With