2011-12-25 27 views
7

Mã đoạn mã từ lexical_cast:Kích hoạt lớp để sử dụng với 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; 
} 

Dựa trên document,

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

1> Trả về kết quả của luồng arg vào một thư viện chuẩn chuỗi dựa trên chuỗi và sau đó là đối tượng Mục tiêu.

2> Nguồn là OutputStreamable

3> Target là InputStreamable

Question1> Cần User Defined Type (UDT), nên các OutputStreamable hoặc InputStreamable luôn phải đối phó với std::string? Ví dụ: cho một lớp có chứa một số nguyên đơn giản làm biến thành viên, khi chúng tôi xác định operator<<operator>>, mã triển khai trông như thế nào? Tôi có phải chuyển đổi số nguyên thành chuỗi không? Dựa trên hiểu biết của tôi, có vẻ như UDT luôn phải đối phó với std::string để làm việc với boost::lexical_castboost::lexcial_cast cần số trung gian std::string để thực hiện các công việc chuyển đổi thực.

question2> Tại sao giá trị trả về của operator<< hoặc operator>> trong mã trên là không tham khảo để std::ostream& hoặc std::istream& tương ứng?

+0

Mã không trả về tham chiếu rất có thể là lỗi, vì luồng không thể sao chép được. – Xeo

+0

Đó là một lỗi mà 'lexical_castable :: read_' là một hàm thành viên const – q0987

+0

Đó là một lỗi mà' lexical_castable :: print' bao gồm một '\ n'. – q0987

Trả lời

7

Để làm cho lớp học của bạn có thể sử dụng được với lexical_cast, chỉ cần xác định toán tử "luồng" cho nó. Từ Boost.LexicalCast Synopsis:

  • Nguồn là OutputStreamable, có nghĩa là một operator<< được định nghĩa mà phải mất một std::ostream hoặc std::wostream đối tượng ở phía bên tay trái và một thể hiện của kiểu lập luận ở bên phải .
  • mục tiêu là InputStreamable, có nghĩa là một operator>> được định nghĩa mà phải mất một std::istream hoặc std::wistream đối tượng ở phía bên tay trái và một thể hiện của kiểu kết quả ở bên phải.
  • Mục tiêu là CopyConstructible [20.1.3].
  • Mục tiêu là DefaultConstructible, có nghĩa là có thể khởi tạo mặc định đối tượng thuộc loại đó [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(); 
} 

Cùng dĩ nhiên cho operator>>.

+0

OP yêu cầu cách lexical_cast trên một số loại có thể được xử lý ** nếu không có ** chuỗi ở giữa. – Kos

+0

@Kos: OP hỏi liệu anh ấy có phải sử dụng ** chuỗi ** mọi lúc không. – Xeo

Các vấn đề liên quan