Sea*_*ean 3 c++ overloading operator-keyword
我有一个使用运算符重载的类,但有一些警告.
// 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];
}
Run Code Online (Sandbox Code Playgroud)
警告是:
>
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&)
Run Code Online (Sandbox Code Playgroud)
从上面的警告来看,应该是问题所在<<.我知道原因,但我怎么能处理这个警告?
谢谢!
问题实际上是你的一个类的构造函数:
base(int n);
Run Code Online (Sandbox Code Playgroud)
这个构造函数就是所谓的转换构造函数.它可以用来将inta 转换为a base,所以这是合法的:
base x = 42;
Run Code Online (Sandbox Code Playgroud)
如果您不想允许此隐式转换,则可以创建构造函数explicit:
explicit base(int n);
Run Code Online (Sandbox Code Playgroud)
有趣的问题是"模糊性在fout << coeff[i];哪里?
有两个候选函数,编译器之间无法决定(或者不应该在它们之间做出决定;您的编译器对您来说"很好"):一个是内置std::ostream operator<<重载,如下所示:
std::ostream& operator<<(std::ostream&, double);
Run Code Online (Sandbox Code Playgroud)
第二个是您的运算符重载,如下所示:
std::ofstream& operator<<(std::ofstream&, const base&);
Run Code Online (Sandbox Code Playgroud)
对于第一个候选者,第一个参数需要派生到基础的转换:std::ofstream需要转换为a std::ostream来调用函数.第二个参数a double完全匹配.
对于第二个候选者,第一个参数a std::ofstream完全匹配.第二个参数需要使用内置的double,以int转换,然后使用您的转换构造从转换int到base.
为了使编译器选择一个候选函数作为要调用的正确函数,每个参数必须至少与候选者的相应参数匹配,并且匹配任何其他候选者.
在这里使用这两个候选者,第一个参数更好地匹配第二个候选者,但第二个参数更好地匹配第一个候选者,因此存在歧义.
另一种解决方案是更改重载,使第一个参数与内置候选项的第一个参数匹配:
std::ostream& operator<<(std::ostream&, const base&);
Run Code Online (Sandbox Code Playgroud)