2011-12-25 16 views
7

fragmento de código lexical_cast:Habilitación de las clases para su uso con impulso :: 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; 
} 

Basado en document,

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

1> devuelve el resultado de la transmisión de arg en una biblioteca estándar secuencia basada en cadena y luego fuera como un objeto Target.

2> Fuente es OutputStreamable

3> Objetivo es InputStreamable

Pregunta1> Por tipo definido por el usuario (UDT), si el OutputStreamable o InputStreamable siempre tienen que tratar con std::string? Por ejemplo, dada una clase que contiene un entero simple como variable miembro, cuando definimos operator<< y operator>>, ¿cómo se ve el código de implementación? ¿Tengo que convertir el número entero como una cadena? En mi entender, parece que UDT siempre tiene que tratar con std::string para trabajar con boost::lexical_cast y boost::lexcial_cast necesita el intermedio std::string para realizar las tareas de conversión reales.

Pregunta2> ¿Por qué el valor de retorno de operator<< o operator>> en el código anterior no se hace referencia a std::ostream& o std::istream&, respectivamente?

+0

Que el código no devuelve una referencia es muy probable que sea un error, ya que las transmisiones no se pueden copiar. – Xeo

+0

Es un error que 'lexical_castable :: read_' es una función de miembro constante – q0987

+0

Es un error que' lexical_castable :: print' incluye un '\ n'. – q0987

Respuesta

7

Para que su clase se pueda utilizar con lexical_cast, simplemente defina los operadores de "transmisión" para ella. De Boost.LexicalCast Synopsis:

  • Fuente es OutputStreamable, lo que significa que un operator<< se define que toma un objeto std::ostream o std::wostream en el lado izquierdo y una instancia del tipo de argumento a la derecha .
  • Target es InputStreamable, lo que significa que un operator>> se define que toma un objeto std::istream o std::wistream en el lado izquierdo y una instancia del tipo de resultado a la derecha.
  • El objetivo es CopyConstructible [20.1.3].
  • El objetivo es DefaultConstructible, lo que significa que es posible inicializar por defecto un objeto de ese 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 mismo, por supuesto, para operator>>.

+0

El OP está preguntando cómo se puede manejar lexical_cast sobre algunos tipos ** sin ** las cadenas de caracteres en el medio. – Kos

+0

@Kos: El OP preguntó si tenía que usar ** cadenas ** todo el tiempo. – Xeo

Cuestiones relacionadas