You can do it as follows:
Save the current possition in input stream by:
streampos pos = is.tellg()
Read the data from stream to some char buffer:
char tmp_buf[expected_size];
read(tmp_buf, expected_size);
// try to create a temporary object from read data
T tmp_obj = T::fromCharBuffer(tmp_buf) // you need to implement that
// If you get a valid object copy it to the destination
obj = tmp_obj
// in case of error revert previous stream position
if (error)
is.seekg(pos)
return is
Ok, ignore all above, I was just wrong:
This topic can help you better:
What's the right way to overload the stream operators << >> for my class?
More elegant solution:
Your have to interprate/validate the data for particular class so you need to implement this functionality somewhere. You have 3 options:
- in particular class
- in some base class
- in friend class of your particular class (best option)
My implementation of approach no.3
class SomeClassParser:
{
// implement the functionality of creating SomeClass from stream.
static SomeClass fromStream(ifstream &if)
{
// do your stream reading here and return SomeClass object
// or throw parsing exception
}
};
class SomeClass:
{
public:
friend SomeClassParser;
// points to the Parser class
typedef SomeClassParser Parser;
...
};
template<typename T>
ifstream& operator<<(ifstream &if, T& obj)
{
// do your type independent work, depending on your needs:
// logging, stream recovery, error handling etc;
// I'm not telling it's good or bad approach to recover the stream after failure
// do what you need here
// save stream
streampos pos = is.tellg()
try
{
obj = T::Parser::fromStream(if);
}
catch (int e):
{
// restore stream
is.seekg(pos);
}
}
With this solution you will not destroy your old object in case the parsing error ocurrs.