2012-10-15 35 views
8

Tôi đang tìm vào cung cấp ostream khai thác đối với một số các lớp học toán (ma trận, vector, vv) Một người bạn đã lưu ý rằng gcc tiêu chuẩn thư viện thực hiện các nhà điều hành ostream cho std::complex bao gồm việc sử dụng nội bộ một chuỗi chuỗi để định dạng đầu ra trước khi chuyển nó tới số thực tế ostream:Sử dụng stringstream bên trong hàm ostream

/// Insertion operator for complex values. 
template<typename _Tp, typename _CharT, class _Traits> 
    basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 
{ 
    basic_ostringstream<_CharT, _Traits> __s; 
    __s.flags(__os.flags()); 
    __s.imbue(__os.getloc()); 
    __s.precision(__os.precision()); 
    __s << '(' << __x.real() << ',' << __x.imag() << ')'; 
    return __os << __s.str(); 
} 

Mẫu này cũng có thể nhìn thấy được. Chúng tôi đang cố gắng xác định xem đây có phải là mẫu có giá trị sau không. Đã có những lo ngại rằng nó liên quan đến việc bao gồm một tiêu đề bổ sung cho luồng chuỗi và có các phân bổ đống bổ sung cần thiết trong luồng chuỗi có khả năng tránh được.

Lý do hợp lý nhất là nếu khách hàng yêu cầu chức năng đó, họ có thể tạo luồng chuỗi và tự thực hiện trước.

Ai đó có thể giúp tôi hiểu tại sao điều này được coi là thực hành tốt hay không và liệu tôi có nên chấp nhận không?

Trả lời

6

Hãy xem xét những gì sẽ xảy ra nếu bạn đặt một chiều rộng đầu ra trên ostream, sau đó viết một std :: phức tạp để nó - bạn không muốn chiều rộng để chỉ ảnh hưởng đến hoạt động sản xuất đầu tiên (tức là nhân vật '(')

std::complex i(0, 1); 
std::cout << std::setw(10) << std::left << i; 

này nên in "(0,1)     " không "(         0,1)"

Bằng cách tạo nên toàn bộ đầu ra như là một chuỗi duy nhất sau đó viết nó ra danh dự đầu ra chiều rộng lĩnh vực và cờ định dạng khác đặt trên suối.

2

Một mục đích chính của mẫu này là tránh giữ lại các thao tác/cờ của luồng ban đầu và đặt lại chúng trước khi trở về. Boost.IoStateSavers obviates sự cần thiết này, vì vậy tôi sẽ nói rằng bằng cách sử dụng thư viện nói sẽ là một thực hành tốt hơn.

4

Lý do luồng được trích dẫn trong phản hồi khác sẽ không thực sự hiệu quả: chuỗi vẫn có thể bị phân chia ở cấp bộ đệm luồng vì các hoạt động này không nguyên tử khi được gọi từ nhiều luồng.

Tuy nhiên, có hai cân nhắc có liên quan:

  1. Đối với một số kết quả đầu ra bạn muốn tạm thời thay đổi các thiết lập định dạng cờ. Ví dụ, bạn muốn chắc chắn rằng một số chuỗi xuất hiện bằng cách sử dụng ký hiệu hex, cho ký hiệu thập phân khác và bạn muốn khôi phục luồng về trạng thái ban đầu của nó.
  2. Quan trọng hơn, ý nghĩa của một đầu ra là width() là số ký tự mà toàn bộ chuỗi định dạng phải chiếm ít nhất. Nếu bạn sử dụng các toán tử đầu ra trong nội bộ cho một toán tử đầu ra khác, bạn sẽ làm cho phần tử đầu tiên chiếm chiều rộng chứ không phải là chuỗi toàn bộ kết quả gồm nhiều thành phần. Ví dụ, đối với một số phức, phần tử thực sẽ chiếm width() thay vì kết hợp phần tử thực, dấu phẩy và phần tử ảo.
Các vấn đề liên quan