流操作符重载问题

时间:2011-01-28 01:28:40

标签: 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];
}

警告是:

&GT;

 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&)

从上面的警告来看,应该是<<的问题。我知道原因,但我怎么能处理这个警告?

谢谢!

1 个答案:

答案 0 :(得分:9)

问题实际上是你的一个类的构造函数:

base(int n);

此构造函数是所谓的转换构造函数。它可用于将int转换为base,因此这是合法的:

base x = 42;

如果您不想允许此隐式转换,可以创建构造函数explicit

explicit base(int n);

有趣的问题是“fout << coeff[i];中的歧义在哪里?

编译器无法决定两个候选函数(或者不应该在它们之间做出决定;您的编译器对您来说是“不错的”):一个是内置的std::ostream { {1}}重载看起来像这样:

operator<<

第二个是您的运算符重载,如下所示:

std::ostream& operator<<(std::ostream&, double);

对于第一个候选者,第一个参数需要派生到基础的转换:std::ofstream& operator<<(std::ofstream&, const base&); 需要转换为std::ofstream以便调用该函数。第二个参数std::ostream完全匹配。

对于第二个候选者,第一个参数double完全匹配。第二个参数需要使用内置的std::ofstreamdouble转换,然后使用转换构造函数将int转换为int

为了让编译器选择一个候选函数作为要调用的正确函数,每个参数必须至少与候选者的相应参数匹配,并且它与任何其他候选者匹配。

这两个候选人在这里,第一个参数更好地匹配第二个候选者,但第二个参数更好地匹配第一个候选者,因此存在歧义。

另一种解决方案是更改重载,使第一个参数与内置候选项的第一个参数匹配:

base