0

I couldn't find a proper example of how to do it properly.

The following code is written in the FAQ.

std::istream& operator>>(std::istream& is, T& obj)
{
  // read obj from stream

if( /* no valid object of T found in stream */ )
    is.setstate(std::ios::failbit);

return is;
}

How do I check if "no valid object of T found in stream" ?

Dannz
  • 495
  • 8
  • 20

1 Answers1

1

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:

  1. in particular class
  2. in some base class
  3. 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.

Community
  • 1
  • 1
woockashek
  • 1,588
  • 10
  • 25
  • What would you imply from `expected_size` regarding the validity of a particular type (remember that is just text read in)? Also how should be `expected_size` set if the input can be `1`, `10` or `100000`? – πάντα ῥεῖ Nov 10 '16 at 10:40
  • @πάνταῥεῖ What can you tell about my current solution? – woockashek Nov 10 '16 at 12:26