2011-01-28 2 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 ...] –

ответ

9

Проблема на самом деле с одним из конструкторов вашего класса:

base(int n); 

Этот конструктор является то, что называется преобразования конструктор. Он может быть использован для преобразования int в base, так что это будет законным:

base x = 42; 

Если вы не хотите, чтобы это неявное преобразование, вы можете сделать конструктор explicit:

explicit base(int n); 

интересный вопрос: «где неоднозначность fout << coeff[i];?

есть две функций кандидатов тх t компилятор не может решить между (или не должен быть в состоянии решить между; ваш компилятор быть «хорошо» к вам): один является встроенный в std::ostreamoperator<< перегрузка, которая выглядит следующим образом:

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

второй ваш перегрузки оператор, который выглядит следующим образом:

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

С первый кандидат, первый аргумент требует преобразования с производной базой: std::ofstream необходимо преобразовать в std::ostream для вызываемой функции. Второй аргумент, double, точно соответствует.

Со вторым кандидатом точно соответствует первый аргумент std::ofstream. Второй аргумент требует использования встроенного преобразования double в int, а затем использования вашего конвертирующего конструктора для преобразования из int в base.

Для того чтобы компилятор мог выбрать одну кандидатную функцию в качестве правой для вызова, каждый из аргументов должен соответствовать, по крайней мере, соответствующему параметру кандидата, а также соответствовать любому другому кандидату.

С этими двумя кандидатами здесь первый аргумент лучше соответствует второму кандидату, но второй аргумент лучше соответствует первому кандидату, поэтому существует двусмысленность.

Альтернативным решением было бы изменить перегрузку таким образом, что первый аргумент совпадает, а также первый аргумент встроенного кандидата:

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

Я бы порекомендовал делать * оба * решения. Определение оператора << для потока только тогда, когда оно будет работать с ostream, а все остальные перегрузки определены для ostream - просто лишнее ограничение. И конструктор, вероятно, должен быть явным в любом случае, потому что объект на самом деле не такой, как integer. –