2012-04-30 13 views
7

Chcę użyć mojej klasy Test z boost::lexical_cast. Mam przeciążony operator<< i operator>>, ale daje mi błąd wykonania.
Oto mój kod:
C++ Korzystanie z klas z doładowaniem :: 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; 
} 

wyjściowa:

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

Btw używam Visual Studio 2010, ale próbowałem Fedorę 16 z g ++ i mam ten sam wynik!

+0

Ciekawe pytanie, nie może znaleźć prawdziwą odpowiedź do tej pory. Wygląda na to, że coś jest nie tak ze strumieniem: 1. ponieważ kiedy dostanie się do operatora strumienia, tylko otrzymasz aktualizację, b nie jest. Dodałem kolejny ciąg znaków, aby sprawdzić, czy przestrzeń została źle zinterpretowana, ale nawet ciąg znaków nie został zaktualizowany. 2. Rzuca się, gdy opuszczasz operatora, sprawdza coś, czego nie rozumiem, a następnie decyduje się rzucić. – Klaim

+0

Powinieneś prawdopodobnie użyć domyślnych wersji domyślnego konstruktora, skopiować konstruktora i destruktora, zamiast samemu je zdefiniować: kompilator wygeneruje je dla ciebie (i zrobi to bardziej poprawnie w przypadku kopiowania konstruktora (zobacz [to jest ] (http://stackoverflow.com/q/4172722/20984)). –

Odpowiedz

7

Twój problem wynika z faktu, że boost::lexical_cast nie ignoruje białych znaków na wejściu (powoduje to usunięcie flagi skipws strumienia wejściowego).

Rozwiązaniem jest albo ustawienie flagi w swoim operatorze ekstrakcji, albo po prostu pominięcie jednego znaku. W rzeczywistości operator wyodrębniania powinien odzwierciedlać operatora wstawiania: ponieważ wyraźnie umieszczasz spację podczas wyprowadzania instancji Test, należy wyraźnie odczytać przestrzeń podczas wyodrębniania instancji.

This thread omawia temat, a zalecanym rozwiązaniem jest wykonanie następujących czynności:

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: Właśnie znalazłem to po 10 minutach szukania co do cholery się dzieje ... – Klaim

+0

Udało się, dzięki! Ale dlaczego oni Właśnie dowiedziałem się, że 'boost :: lexical_cast (" 123 ")' rzuca ten sam wyjątek! –

+0

To pytanie zostało szczegółowo omówione na forach Boost [Ten wątek] (http: //lists.boost. org/Archives/boost/2005/01/79275.php) jest dość interesujący pod tym względem. –