2011-12-25 13 views
7

snippet di codice lexical_cast:Abilitazione Classi per l'utilizzo con boost :: lexical_cast

class lexical_castable { 
public: 
    lexical_castable() {}; 
    lexical_castable(const std::string s) : s_(s) {}; 

    friend std::ostream operator<< 
    (std::ostream& o, const lexical_castable& le); 
    friend std::istream operator>> 
    (std::istream& i, lexical_castable& le); 

private: 
    virtual void print_(std::ostream& o) const { 
    o << s_ <<"\n"; 
    } 

    virtual void read_(std::istream& i) const { 
    i >> s_; 
    } 

    std::string s_; 
}; 

std::ostream operator<<(std::ostream& o, 
    const lexical_castable& le) { 
    le.print_(o); 
    return o; 
} 

std::istream operator>>(std::istream& i, lexical_castable& le) { 
    le.read_(i); 
    return i; 
} 

Sulla base di document,

template<typename Target, typename Source> 
    Target lexical_cast(const Source& arg); 

1> restituisce il risultato di streaming di arg in una libreria standard flusso basato su stringhe e quindi fuori come oggetto Target.

2> Source è OutputStreamable

3> Target è InputStreamable

Question1> Per User Defined Type (UDT), deve l'OutputStreamable o InputStreamable hanno sempre a che fare con std::string? Ad esempio, data una classe contenente un numero intero semplice come variabile membro, quando definiamo lo operator<< e operator>>, come è il codice di implementazione? Devo convertire il numero intero come stringa? Sulla base della mia comprensione, sembra che l'UDT debba sempre occuparsi di std::string per lavorare con boost::lexical_cast e boost::lexcial_cast e che abbia bisogno dello intermedio std::string per eseguire i veri lavori di conversione.

Question2> Perché il valore di ritorno di operator<< o operator>> nel codice di cui sopra non è il riferimento rispettivamente std::ostream& o std::istream&?

+0

Che il codice non restituisca un riferimento è molto probabile un bug, poiché gli stream non sono copiabili. – Xeo

+0

È un errore che 'lexical_castable :: read_' è una funzione membro const – q0987

+0

È un errore che' lexical_castable :: print' include un '\ n'. – q0987

risposta

7

Per rendere la classe utilizzabile con lexical_cast, è sufficiente definire gli operatori "flusso" per esso. Da Boost.LexicalCast Synopsis:

  • Source è OutputStreamable, che significa che un operator<< è definita che accetta un oggetto std::ostream o std::wostream sul lato sinistro e un'istanza del tipo argomento sulla destra .
  • target è InputStreamable, che significa che un operator>> è definita che accetta un oggetto std::istream o std::wistream sul lato sinistro e un'istanza del tipo di risultato sulla destra.
  • Target is CopyConstructible [20.1.3].
  • L'obiettivo è DefaultConstructible, ovvero è possibile inizializzare l'oggetto predefinito di quel tipo [8.5, 20.1.4].

:

// either inline friend, out-of-class friend, or just normal free function 
// depending on whether it needs to access internel members 
// or can cope with the public interface 
// (use only one version) 
class MyClass{ 
    int _i; 
public: 
    // inline version 
    friend std::ostream& operator<<(std::ostream& os, MyClass const& ms){ 
    return os << ms._i; 
    } 

    // or out-of-class friend (friend declaration inside class only) 
    friend std::ostream& operator<<(std::ostream& os, MyClass const& ms); 

    // for the free function version 
    int get_i() const{ return _i; } 
}; 

// out-of-class continued 
std::ostream& operator<<(std::ostream& os, MyClass const& ms){ 
    return os << ms._i; 
} 

// free function, non-friend 
std::ostream& operator<<(std::ostream& os, MyClass const& ms){ 
    return os << ms.get_i(); 
} 

Lo stesso, naturalmente, per operator>>.

+0

L'OP chiede come sia possibile gestire lexical_cast su alcuni tipi ** senza ** le stringhe intermedie. – Kos

+0

@Kos: l'OP ha chiesto se doveva usare ** stringhe ** tutto il tempo. – Xeo

Problemi correlati