views:

482

answers:

7

I've written tons of operator<<(std::ostream &, const T &) functions -- they're incredibly useful.

I've never written an operator>>(std::istream &, T &) function in real code or even used the extraction operators for built-in types (OK, maybe for std::string). Are these appropriate only for short example programs and textbooks? Is operator>> a failed feature of C++?

Questions have been asked about safely overloading stream operators. What I wonder is if anyone does this in practice.

Even for something simple like reading input from a file in C++ I can't suggest using operator>>. It's too difficult to write code that is robust in detecting and handling errors in input (or I don't know how).

If you disagree please show a good example of using operator>> -- maybe by answering that last question I linked to.


Wrapup: Thanks for the responses everyone, lots of good opinions. Manuel's answer made me reconsider my reluctance to using op>> so I accepted that one.

+2  A: 

Values are more often printed than read, so operator<< is used more often than operator>>. Nevertheless, if you want to read values, operator>> is useful.

That you have to check for errors is not specific to operator>>, obviously also any other way to read values will have to detect invalid input in some way.

sth
A: 

I made heavy use of operator<< to assemble lists of sort instructions, fields into database views etc. in my OOFILE database API.

For some reason, a large number of users found it intuitive to use the operator>> to append a sort field which was a reverse sort. I don't know who suggested it in the first place but it appealed to enough people that it made it in the API.

eg:

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 

We also made conventional use of operator>> to parse an entire dbTable from a stream.

Andy Dent
OK, but that's not an istream extractor. I've used op>> for writing marshaling code, where I had complete control over the input/output and any error was fatal. But I've never found it useful for text processing.
Dan
I just corrected myself - OOFILE uses the conventional pattern of operator>> calling a virtual insert method for tables and fields.
Andy Dent
+1  A: 

Operator >> is basically deserialization. In my limited and anecdotal experience, most serialization/deserialization in C++ is implemented at a lower level than the stream library. It doesn't have to be implemented at a lower level - it just usually is.

Implementing custom deserialization isn't always a trivial problem, but you're likely to run into the same issues even if you don't implement it with stream extraction syntax.

Here's a cheezy use of the stream extraction operator that is at least marginally useful: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

In this limited scope, it seems like correct usage is fairly simple.

Merlyn Morgan-Graham
That's an interesting example, because it puts a `string` into an `istringstream`. The consequence is that if there is a parse failure, the original input can be displayed to the user. Vs. if the code was reading directly from an `istream`, by the time the failure occurred, it's too late to display the bad input.
Dan
File and network streams are useful examples, too. Implementing any sort of deserialization at the byte stream level is going to be messy, unless your needs are very basic. For bigger needs, you should design a protocol, and then implement that. Specific error handling (and maybe error recovery and/or data redundancy) can be designed in, in which case the code then will become obvious.
Merlyn Morgan-Graham
+5  A: 

Yes I do use operator>> (although not as frequently as operator<<). It is very useful for parsing user defined types into their respective objects and hence centralizing the parsing and necessary error processing. It is also very useful for parsing the string representation of an enumerated type.

For example, consider an enumerated type representing a fruit. You can use operator>> to parse a string (like "apple", "banana", etc.) to obtain the correct enumeration value.

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;
}

Note also the use of the setstate method on the istream to set the failure state of the stream when an unknown string is encountered. When using this operator, you can check the failstate of the stream as follows:

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

I never write them, and quite rarely use the "built-in" ones. The extraction operators are pretty useless for reading interactive user input, because it is too easy for a stream to go bad. Writing a custom parsing routine is almost always easier and more robust. And when it comes to serialisation, if I want to save something as text, I do it to an industry-standard format such as XML, which the extraction operators are notably ill-suited to read. Otherwise I store the data on a database or in binary file, which once again are ill-suited for use with extractors.

anon
+2  A: 

operator>> is useful in converting numbers in text form to an internal representation.

It can also be useful in loading data for objects. Unlike scanf, which cannot be overloaded for different types, objects can overload operator>>. Thus it provides more data hiding for loading objects, the internal representation does not need to be known in order to read data into the object.

Thomas Matthews
+4  A: 

I think stream extractor operators can be very useful when combined with STL algorithms like std::copy and with the std::istream_iterator class.

Read this answer to see what I'm talking about.

Manuel
I like that technique. I'll have to try it sometime.
Dan