2011-01-28 7 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); 

이 생성자는 생성자을 변환 라고하는 것이다. baseint을 변환 할 수 있습니다, 그래서 이것은 법적 것 :

explicit base(int n); 
:이 암시 적 변환을 허용하지 않으려면

base x = 42; 

, 당신은 생성자 explicit을 만들 수 있습니다


흥미로운 질문은 두 후보 함수 그쪽이 어디에 fout << coeff[i];?

의 모호성이다 "입니다 컴파일러는 그 사이를 결정할 수 없다 (또는 그 사이를 결정할 수 없어야한다; 컴파일러는) 당신에게 "좋은"되고 있습니다 :

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

으로 :

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

두 번째 모습 운영자 과부하가 있습니다 : 하나는 다음과 같습니다 내장 std::ostreamoperator<< 과부하입니다 첫 번째 인수는 첫 번째 인수에 파생 - 기반 변환이 필요합니다. 은 호출 할 함수에 대해 std::ostream으로 변환해야합니다. 두 번째 인수 인 double은 정확히 일치합니다.

두 번째 후보는 첫 번째 인수 인 std::ofstream이 정확히 일치합니다. 두 번째 인수는 내장형 double ~ int 변환을 사용하고 변환 생성자를 사용하여 int에서 base으로 변환해야합니다.

컴파일러가 하나의 후보 함수를 호출 할 올바른 함수로 선택하려면 각 인수가 후보의 해당 매개 변수와 적어도 일치해야하며 다른 후보와 일치해야합니다.

여기서 두 후보는 첫 번째 인수가 두 번째 후보와 잘 일치하지만 두 번째 인수는 첫 번째 후보와 더 잘 일치하므로 모호한 점이 있습니다.당신이 할 수 있습니다 롤 - 다시 내 편집 -

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

나는 * both * solutions을하는 것이 좋습니다. ofstream에서만 ostream에 대해 연산자 <<를 정의하고 ostream에 대해서는 다른 모든 과부하를 정의하는 것은 불필요한 제한입니다. 그리고 객체가 정수와 실제로 같지 않기 때문에 생성자는 어쨌든 명시 적이어야합니다. –