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 overloadin开发者_StackOverflowg 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.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.
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;
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.
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.
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.
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.
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.
精彩评论