2011-01-28 61 views
3

我有一個類使用操作符重載,但有一些警告。流操作符重載問題

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

從上述警告,它應該是的<<的問題。我知道原因,但我怎麼處理這個警告?

謝謝!

+0

哎呀 - 您可能希望回滾我的編輯。我道歉。看起來我們三個人正在編輯。 [編輯:使5或7 ...] – 2011-01-28 01:32:19

回答

9

這個問題實際上是你的類的構造函數:

base(int n); 

此構造是所謂的轉換構造。它可以用來給int轉換爲base,所以這將是合法的:

base x = 42; 

如果您不希望允許這種隱式轉換,可以使構造explicit

explicit base(int n); 

有趣的問題是:「這裏是fout << coeff[i];

歧義有兩個候選函數塔編譯器無法做出決定(或不應該能夠決定;你的編譯器是被「好」給你):一個是內置std::ostreamoperator<<超載,看起來像這樣:

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

二是看起來像你的運算符重載:

std::ofstream& operator<<(std::ofstream&, const base&); 

隨着第一個候選者,第一個參數需要導出到基礎的轉換:std::ofstream需要轉換爲std::ostream以便調用該函數。第二個參數double完全匹配。

第二個候選人第一個參數std::ofstream完全匹配。第二個參數需要使用內置的doubleint轉換,然後使用您的轉換構造函數從int轉換爲base

爲了使編譯器選擇一個候選函數作爲調用的正確參數,每個參數必須至少匹配候選對應的參數,並且它至少與其他候選匹配。

在這裏有兩個候選人,第一個參數更好地匹配第二個候選人,但第二個參數匹配第一個候選人更好,因此存在不明確性。

另一種解決辦法是改變你的過載,使得第一參數匹配,以及內置的候選人的第一個參數:

std::ostream& operator<<(std::ostream&, const base&); 
+0

我會建議做*兩個*解決方案。定義運營商<< forstream只有當它可以與ostream一起使用,並且爲ostream定義所有其他重載時纔是不必要的限制。無論如何,構造函數可能應該是明確的,因爲該對象與整數不完全相同。 – 2011-02-04 20:31:23