2012-04-30 9 views
7

Quiero usar mi clase Test con boost::lexical_cast. He sobrecargado operator<< y operator>> pero me da error de tiempo de ejecución.
Aquí está mi código:
C++ Uso de clases con boost :: lexical_cast

#include <iostream> 
#include <boost/lexical_cast.hpp> 
using namespace std; 

class Test { 
    int a, b; 
public: 
    Test() { } 
    Test(const Test &test) { 
     a = test.a; 
     b = test.b; 
    } 
    ~Test() { } 

    void print() { 
     cout << "A = " << a << endl; 
     cout << "B = " << b << endl; 
    } 

    friend istream& operator>> (istream &input, Test &test) { 
     input >> test.a >> test.b; 
     return input; 
    } 

    friend ostream& operator<< (ostream &output, const Test &test) { 
     output << test.a << test.b; 
     return output; 
    } 
}; 

int main() { 
    try { 
     Test test = boost::lexical_cast<Test>("10 2"); 
    } catch(std::exception &e) { 
     cout << e.what() << endl; 
    } 
    return 0; 
} 

Salida:

bad lexical cast: source type value could not be interpreted as target 

Por cierto estoy usando Visual Studio 2010 pero he intentado Fedora 16 con g ++ y obtuvo el mismo resultado!

+0

Interesante pregunta, no puede encontrar la verdadera respuesta hasta el momento. Parece que algo está mal con la transmisión: 1. porque cuando ingresa al operador de transmisión, solo se actualiza, b no lo es. Agregué otra cadena para verificar si el espacio fue mal interpretado, pero incluso la cadena no se actualizó. 2. Se lanza cuando sales del operador, comprueba algo que no entiendo y luego decide tirar. – Klaim

+0

Probablemente deberías usar las versiones predeterminadas del constructor predeterminado, el constructor de copias y el destructor, en lugar de definirlas tú mismo: el compilador las generará (y lo hará de forma más correcta en el caso de que copies el constructor (ver [este faq ] (http://stackoverflow.com/q/4172722/20984)). –

Respuesta

7

Su problema proviene del hecho de que boost::lexical_cast no ignora los espacios en blanco en la entrada (desactive la bandera skipws del flujo de entrada).

La solución es establecer la bandera usted mismo en su operador de extracción o simplemente omitir un carácter. De hecho, el operador de extracción debe reflejar el operador de inserción: dado que usted explícitamente coloca un espacio cuando da salida a una instancia de Test, debe leer explícitamente el espacio al extraer una instancia.

This thread discute el tema, y ​​la solución recomendada es hacer lo siguiente:

friend std::istream& operator>>(std::istream &input, Test &test) 
{ 
    input >> test.a; 
    if((input.flags() & std::ios_base::skipws) == 0) 
    { 
     char whitespace; 
     input >> whitespace; 
    } 
    return input >> test.b; 
} 
+0

+1: Acabo de encontrarlo yo mismo después de 10 minutos de búsqueda de qué demonios estaba pasando ... – Klaim

+0

Funcionó, ¡Gracias! Pero ¿por qué Esto acaba de descubrir 'boost :: lexical_cast (" 123 ")' arroja la misma excepción! –

+0

Esta pregunta se ha discutido ampliamente en los foros de Boost. [Este hilo] (http: //lists.boost. org/Archives/boost/2005/01/79275.php) es bastante interesante en este sentido. –

Cuestiones relacionadas