2010-02-22 26 views
21

Tôi đã viết tấn các hàm operator<<(std::ostream &, const T &) - chúng cực kỳ hữu ích.Có ai thực sự sử dụng toán tử trích xuất luồng không?

Tôi chưa bao giờ viết hàm operator>>(std::istream &, T &) bằng mã thực hoặc thậm chí sử dụng toán tử khai thác cho các kiểu được tích hợp sẵn (OK, có thể là std::string). Những điều này chỉ thích hợp cho các chương trình và sách giáo khoa ví dụ ngắn không? Có phải operator>> là một tính năng không thành công của C++ không?

Câu hỏi đã được hỏi về safely overloading stream operators. Những gì tôi tự hỏi là nếu có ai làm điều này trong thực tế.

Ngay cả đối với một cái gì đó đơn giản như reading input from a file in C++ Tôi không thể đề xuất sử dụng operator>>. Quá khó để viết mã mạnh mẽ trong việc phát hiện và xử lý lỗi trong đầu vào (hoặc tôi không biết làm thế nào).

Nếu bạn không đồng ý, hãy hiển thị ví dụ về cách sử dụng operator>> - có thể bằng cách trả lời câu hỏi cuối cùng mà tôi liên kết đến.


Kết thúc: Cảm ơn bạn đã trả lời tất cả mọi người, rất nhiều ý kiến ​​hay. Câu trả lời của Manuel khiến tôi xem xét lại sự miễn cưỡng của mình khi sử dụng op>> vì vậy tôi đã chấp nhận điều đó.

+0

Bạn cần xác định 'op >>' nếu để hỗ trợ 'lexical_cast'. (http://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm). – kennytm

Trả lời

8

Tôi nghĩ rằng các toán tử trích xuất luồng có thể rất hữu ích khi được kết hợp với các thuật toán STL như std::copy và với lớp std::istream_iterator.

Đọc this answer để xem tôi đang nói về điều gì.

+0

Tôi thích kỹ thuật đó. Tôi sẽ phải thử nó đôi khi. – Dan

3

Giá trị thường được in hơn đã đọc, do đó, operator<< được sử dụng thường xuyên hơn operator>>. Tuy nhiên, nếu bạn muốn đọc giá trị, operator>> hữu ích.

Bạn phải kiểm tra lỗi không cụ thể đối với operator>>, rõ ràng là bất kỳ cách nào khác để đọc các giá trị sẽ phải phát hiện đầu vào không hợp lệ theo một cách nào đó.

0

Tôi đã sử dụng nhiều toán tử < < để tập hợp danh sách hướng dẫn sắp xếp, trường vào chế độ xem cơ sở dữ liệu v.v. trong API cơ sở dữ liệu OOFILE của tôi.

Vì lý do nào đó, một số lượng lớn người dùng thấy nó trực quan để sử dụng toán tử >> đến append a sort field which was a reverse sort. Tôi không biết ai đề xuất nó ở nơi đầu tiên nhưng nó kêu gọi đủ người mà nó đã làm cho nó trong API.

ví dụ:

dbSorter arcSort; // declare a sorter 
arcSort << reverse(Date) << FileName; // "normal" way to specify two sort fields 
arcSort >> Date << FileName; // shorthand way that evolved to specify 

Chúng tôi cũng đã sử dụng thông thường của operator >> để phân tích toàn bộ dbTable từ một dòng suối.

+0

OK, nhưng đó không phải là bộ giải nén istream. Tôi đã sử dụng op >> để viết mã marshaling, nơi tôi đã hoàn toàn kiểm soát đầu vào/đầu ra và bất kỳ lỗi nào đều gây tử vong. Nhưng tôi chưa bao giờ thấy nó hữu ích cho việc xử lý văn bản. – Dan

+0

Tôi chỉ sửa chữa bản thân mình - OOFILE sử dụng mô hình toán tử thông thường >> gọi phương thức chèn ảo cho các bảng và trường. –

1

Nhà điều hành >> về cơ bản là deserialization. Trong kinh nghiệm giới hạn và giai thoại của tôi, hầu hết serialization/deserialization trong C++ được thực hiện ở mức thấp hơn so với thư viện stream. Nó không phải được thực hiện ở một mức độ thấp hơn - nó chỉ thường là.

Triển khai tùy chỉnh deserialization không phải luôn luôn là một vấn đề tầm thường, nhưng bạn có khả năng chạy vào cùng một vấn đề ngay cả khi bạn không thực hiện nó với cú pháp trích xuất luồng.

Dưới đây là một sử dụng cheezy của các nhà điều hành khai thác dòng ít nhất là nhẹ hữu ích: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

Trong phạm vi giới hạn này, nó có vẻ như sử dụng đúng là khá đơn giản.

+0

Đó là một ví dụ thú vị, bởi vì nó đặt một 'chuỗi' vào một' istringstream'. Hậu quả là nếu có lỗi phân tích cú pháp, đầu vào ban đầu có thể được hiển thị cho người dùng. Vs. nếu mã được đọc trực tiếp từ 'istream', vào thời điểm xảy ra lỗi, đã quá muộn để hiển thị đầu vào không hợp lệ. – Dan

+0

Luồng tệp và mạng là các ví dụ hữu ích. Thực hiện bất kỳ loại deserialization ở cấp dòng byte sẽ được lộn xộn, trừ khi nhu cầu của bạn là rất cơ bản. Đối với các nhu cầu lớn hơn, bạn nên thiết kế một giao thức, và sau đó thực hiện điều đó. Cụ thể xử lý lỗi (và có thể phục hồi lỗi và/hoặc dự phòng dữ liệu) có thể được thiết kế, trong trường hợp đó mã sau đó sẽ trở nên rõ ràng. –

6

Có Tôi sử dụng toán tử >> (mặc dù không thường xuyên như toán tử < <).Nó rất hữu ích cho việc phân tích cú pháp người dùng định nghĩa các loại vào các đối tượng tương ứng của họ và do đó tập trung phân tích cú pháp và xử lý lỗi cần thiết. Nó cũng rất hữu ích để phân tích cú pháp biểu diễn chuỗi của một kiểu liệt kê.

Ví dụ: hãy xem xét loại được liệt kê đại diện cho một loại trái cây. Bạn có thể sử dụng toán tử >> để phân tích một chuỗi (như "táo", "chuối", v.v.) để có được giá trị điều tra chính xác.

std::istream &operator>>(std::istream &is, Fruit &fruit) 
{ 
    std::string str; 
    is >> str; 
    if (str == "apple") 
     fruit = APPLE; 
    else if (str == "banana") 
     fruit = BANANA; 
    // other fruits 
    else 
     is.setstate(std::ios::failbit); 
    return is; 
} 

Cũng lưu ý sử dụng phương pháp setstate trên luồng để đặt trạng thái lỗi của luồng khi gặp phải chuỗi không xác định. Khi sử dụng toán tử này, bạn có thể kiểm tra tuyến thất bại của luồng như sau:

Fruit fruit; 
std::cin >> fruit; 
if (std::cin.fail()) 
    std::cout << "Error: Unknown Fruit!" << std::endl; 
2

Tôi không bao giờ viết chúng và hiếm khi sử dụng "tích hợp sẵn". Các nhà khai thác khai thác là khá vô dụng để đọc đầu vào người dùng tương tác, bởi vì nó là quá dễ dàng cho một dòng để đi xấu. Viết một thói quen phân tích cú pháp tùy chỉnh hầu như luôn luôn dễ dàng hơn và mạnh mẽ hơn. Và khi nói đến serialization, nếu tôi muốn lưu một cái gì đó như văn bản, tôi làm điều đó với một định dạng tiêu chuẩn công nghiệp như XML, mà các nhà khai thác khai thác đáng chú ý là không phù hợp để đọc. Nếu không, tôi lưu trữ dữ liệu trên cơ sở dữ liệu hoặc trong tệp nhị phân, một lần nữa sẽ không phù hợp để sử dụng với bộ nhổ.

2

operator>> hữu ích trong việc chuyển đổi số ở dạng văn bản thành biểu diễn nội bộ.

Nó cũng có thể hữu ích trong việc tải dữ liệu cho các đối tượng. Không giống như scanf, không thể quá tải cho các loại khác nhau, các đối tượng có thể quá tải operator>>. Do đó nó cung cấp nhiều ẩn dữ liệu hơn cho các đối tượng tải, biểu diễn bên trong không cần phải biết để đọc dữ liệu vào đối tượng.

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