2011-12-25 3 views
7

фрагмент кода из lexical_cast:Включение классов для использования с повышением :: 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; 
} 

на основе document,

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

1> Возвращает результат потокового ARG в стандартную библиотеку потоковый поток, а затем в качестве целевого объекта.

2> Источник является OutputStreamable

3> Target является InputStreamable

Question1> Для User Defined Type (UDT), если OutputStreamable или InputStreamable всегда приходится иметь дело с std::string? Например, если класс, содержащий простое целое в качестве переменной-члена, когда мы определяем operator<< и operator>>, будет выглядеть код реализации? Нужно ли преобразовать целое число в виде строки? Основываясь на моем понимании, кажется, что UDT всегда имеет дело с std::string, чтобы работать с boost::lexical_cast, а boost::lexcial_cast нуждается в промежуточном std::string для выполнения реальных заданий преобразования.

Вопрос2> Почему возвращаемое значение operator<< или operator>> в коде выше, не ссылаться на std::ostream& или std::istream& соответственно?

+0

Что код не возвращает ссылку, скорее всего, ошибка, так как потоки не могут быть скопированы. – Xeo

+0

Это ошибка, из-за которой 'lexical_castable :: read_' является функцией-членом-константой. – q0987

+0

Это ошибка, которую' lexical_castable :: print' включает в себя '\ n'. – q0987

ответ

7

Чтобы сделать ваш класс пригодным для использования с помощью lexical_cast, просто определите для него «потоковые» операторы. От Boost.LexicalCast Synopsis:

  • Источник является OutputStreamable, что означает, что operator<< определено, что принимает std::ostream или std::wostream объект на левой стороне и экземпляр типа аргумента на праве ,
  • Задача является InputStreamable, а это означает, что operator>> определено, что принимает std::istream или std::wistream объект на левой стороне и экземпляр типа результата справа.
  • Target is CopyConstructible [20.1.3].
  • Target is DefaultConstructible, что означает, что по умолчанию можно инициализировать объект такого типа [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(); 
} 

То же самое, конечно, для operator>>.

+0

OP задает вопрос о том, как можно обрабатывать lexical_cast по некоторым типам ** без ** потоков строк между ними. – Kos

+0

@ Kos: ОП спросил, должен ли он использовать ** строки ** все время. – Xeo