2011-01-09 12 views
5

Ich habe den folgenden Code:überladener Operator << auf ofstream Verkettung Problemen

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; 
} 

Ich versuche, warum # 1 Werk zu verstehen, während es Probleme gibt beim Versuch, den überladenen Operator zu verwenden, um es wie in verketten # 2, das mit dem folgenden Fehler fehlschlägt (gcc 4.5.3 auf Mac OS X):

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]'

Alles ist stattdessen in Ordnung, wenn ich meinen Bediener als

std::ostream &operator << (std::ostream &f, const simple &obj) 
{ ... } 
definieren

Klingt wie etwas, das mit der Überladungsauflösung zusammenhängt, wo etwas in den Ofstream eingefügt wurde, für das es bereits eine Überlastung gibt (das const char * "label" in diesem Fall) bricht nach Überladung auf, kann aber nicht wirklich verstehe was genau hier vorgeht. Ich mag ein klares Bild von dem, was der Compiler versucht ..

+1

Ich weiß nicht genau, warum der Compiler sich beschwert, aber das Überladen für 'ostream' (d. H. Die gemeinsame Basisklasse) ist das Richtige, da es für alle Arten von Ausgabeströmen verwendet werden kann. –

Antwort

16

auf der Linie zu tun bekommen:

f << "label: " << s; 

Da der erste Aufruf von operator<< ein std::ostream & zurückgibt, schlägt der zweite zu kompilieren: Der linke Operand für den Operator ist nicht mehr vom Typ std::ofstream und Ihre Überladung wurde nicht gefunden.

Sie sollten wirklich die zweite Signatur verwenden, da ich keinen Grund sehe, den Typ auf std::ofstream zu beschränken.

+0

Allerdings sollte 'f << s <<" label: "' funktionieren! – Nawaz

+2

Sie können die Funktion weiter verallgemeinern, um mit beliebigen Charaktereigenschaften zu arbeiten, wenn Sie die Signatur 'template std :: basic_ostream & operator << (std :: basic_ostream & s, const einfach & obj);' verwenden – wilhelmtell