2011-01-09 16 views
5

나는 다음과 같은 코드가 있습니다오버로드 된 연산자 <<

struct simple 
{ 
    simple (int a1, int a2) : member1(a1), member2(a2) {} 
    int member1; 
    int member2; 
}; 

std::ofstream &operator << (std::ofstream &f, const simple &obj) 
{ 
    f<<obj.member1<<", "<<obj.member2; 
    return f; 
} 
int main(int argc, const char *argv[]) 
{ 
    std::ofstream f("streamout.txt"); 

    simple s(7,5); 
    f << s;    //#1 This works 
    f << "label: " << s; //#2 This fails 

    return 0; 
} 

내가 같이 그것을 연결 오버로드 된 연산자를 사용하려고 할 때 문제가있는 동안, 왜 # 1 작품을 이해하려고 노력 중이 야 (에서라도에 GCC 4.5.3) 다음 오류와 함께 실패 # 2 : 나는

std::ostream &operator << (std::ostream &f, const simple &obj) 
{ ... } 
나의 연산자를 정의하는 경우

error: cannot bind 'std::basic_ostream' lvalue to 'std::basic_ostream&&' /GCC-FACTORY/4.5/INSTALL/lib/gcc/x86_64-apple-darwin10.5.0/4.5.3/../../../../include/c++/4.5.3/ostream:579:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits, _Tp = simple]'

모든 대신 괜찮습니다

과부하 해결과 관련한 소리, 이미 오버로드가있는 ofstream에 삽입 된 것이 있으면 (이 경우 const char * "label") 과부하 해결 후 깨지기 쉽지만 실제로는 정확히 여기서 무슨 일이 일어나는지 이해하십시오. 내가 뭘 컴파일러의이 .. 라인에

+1

필자는 왜 컴파일러가 불만을 제기하는지 정확히 알지 못하지만 모든 종류의 출력 스트림에 사용할 수 있으므로 'ostream'에 대한 오버로드 (즉, 공통 기본 클래스)가 올바른 작업입니다. –

답변

16

하려고 노력의 명확한 그림 좀하고 싶습니다 :

f << "label: " << s; 

operator<<에 대한 첫 번째 호출은 std::ostream &을 반환하므로를, 두 번째는 컴파일에 실패 : 연산자에 대한 왼쪽 피연산자는 더 이상 std::ofstream 유형이 아니며 오버로드를 찾을 수 없습니다.

출력 형식을 std::ofstream으로 제한 할 이유가 없기 때문에 실제로 두 번째 서명을 사용해야합니다.

+0

그러나'f << s << "레이블 :"'그래도 작동합니다! – Nawaz

+2

서명'template std :: basic_ostream & operator << (std :: basic_ostream & s, const simple & obj);')를 사용하면 더 많은 성격을 가진 함수를 일반화 할 수 있습니다. – wilhelmtell