流运算符重载问题
我有一个使用运算符重载的类,但有一些警告。
// 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];
}
警告是:
>
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&)
从上面的警告来看,应该是<<
的问题。我知道原因,但是我该如何处理这个警告呢?
谢谢你!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题实际上出在类的构造函数之一上:
这个构造函数就是所谓的转换构造函数。它可用于将
int
转换为base
,因此这是合法的:如果您不想允许这种隐式转换,您可以使构造函数 < code>explicit:
有趣的问题是“fout << coeff[i]; 中的歧义在哪里?
编译器无法在两个候选函数之间做出决定(或者不应该在两者之间做出决定;你的编译器对你“很好”):一个是内置的
std::ostream
operator<<
重载看起来像这样:第二个是你的运算符重载,看起来像:
对于第一个候选者,第一个参数需要派生到基的转换:
std::ofstream
需要转换为std::ostream
表示要调用的函数,第二个参数是 double,与第二个参数(第一个参数是 std) 完全匹配。 :ofstream,完全匹配第二个参数需要使用内置的
double
到int
转换,然后使用转换构造函数从 < 进行转换。代码>int到base
。为了让编译器选择一个候选函数作为正确的调用函数,每个参数必须至少与候选函数的相应参数匹配,并且与任何其他候选函数匹配。
对于这两个候选,第一个参数与第二个候选更好匹配,但第二个参数与第一个候选更好匹配,因此存在歧义。
另一种解决方案是更改重载,使第一个参数与内置候选者的第一个参数匹配:
The problem is actually with one of your class's constructors:
This constructor is what is called a converting constructor. It can be used to convert an
int
to abase
, so this would be legal:If you don't want to allow this implicit conversion, you can make the constructor
explicit
: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:the second is your operator overload that looks like:
With the first candidate, the first argument requires a derived-to-base conversion: the
std::ofstream
needs to be converted to astd::ostream
for the function to be called. The second argument, adouble
, matches exactly.With the second candidate, the first argument, a
std::ofstream
, matches exactly. The second argument requires the use of the built-indouble
toint
conversion then the use of your converting constructor to convert fromint
tobase
.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: