I\'ve written tons of operator<<(std::ostream &, const T &)
functions -- they\'re incredibly useful.
I\'ve never written an operator
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.
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.
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.
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.
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;
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.