2011-01-09 19 views
5

Tengo el siguiente código:operador sobrecargado << en problemas de concatenación ofstream

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

estoy tratando de entender por qué # 1 obras, mientras que hay problemas cuando se intenta utilizar el operador sobrecargado concatenándolo como en # 2 que se produce el siguiente error (gcc 4.5.3 MacOSX):

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

Todo está en su lugar, si bien defino mi operador

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

Suena como algo relacionado con la sobrecarga de resolución, donde tener un algo insertado en el ofstream para los que ya hay una sobrecarga de siempre (la const char * "etiqueta" en este caso) se rompe siguiente resolución de sobrecarga, pero no puedo entender qué está pasando exactamente aquí. me gustaría obtener una imagen clara de lo que el compilador está tratando de hacer ..

+1

No sé específicamente por qué el compilador se queja, pero la sobrecarga de 'ostream' (es decir, la clase base común) es lo correcto a hacer, ya que permite que pueda ser utilizado para todo tipo de flujos de salida. –

Respuesta

16

En la línea:

f << "label: " << s; 

Debido a que la primera llamada a operator<< devuelve un std::ostream &, la segunda falla al compilar: el operando izquierdo para el operador ya no es del tipo std::ofstream y su sobrecarga no se encuentra.

Realmente debería utilizar la segunda firma, ya que no veo ninguna razón para restringir su tipo a la salida al std::ofstream.

+0

Sin embargo, la etiqueta 'f << s <<": "' debería funcionar! – Nawaz

+2

Puede generalizar más la función para trabajar con cualquier rasgo de carácter si usa la firma 'plantilla std :: basic_ostream & operator << (std :: basic_ostream & s, const simple & obj);' – wilhelmtell