I'm writing a custom >>
operator, which reads an entire stream character by character and updates an object with each character, something like this:
class MyClass
{
public:
bool Process(char c);
}
std::istream& operator>>(std::istream& input, MyClass& value)
{
if (input)
{
char c;
bool parsing_success = true;
while (parsing_success && input >> c)
{
parsing_success = value.Process(c)
}
if (!parsing_success)
input.setstate(std::ios_base::failbit);
}
return input;
}
The idea is that the stream is read character by character, until reaching the end of the stream or until a character that MyClass
doesn't like is encountered. When the latter happens, the operator will raise an error.
I'm intending for it to be used like this:
MyClass value;
if (std::cin >> value)
{
//do something with value
}
else
{
//handle error
}
The issue I'm encountering is that after the entire stream is read, istream::fail()
returns true because the end of the stream was reached, which sets both eof
and fail
(as shown in other questions like this).
As a result std::cin >> value
returns false even when the stream was processed successfully.
Now, the caller of the operator could potentially check if the eof
bit is set, but I feel like this isn't idiomatic with other standard usage patterns of the >>
operator - e.g. int x; if (cin >> x) { //do something }
.
So my question is - Should I be calling istream::clear after successfully processing the stream?. Something like this:
if (!parsing_success)
input.setstate(std::ios_base::failbit);
else
input.clear();
That would clear the failbit and ensure that std::cin >> value
would only return false if there's a legitimate stream error, or if an invalid character was encountered. However, I'm just not sure if this is idiomatic C++ or would cause other issues.
Thanks!