Well, let's try ... Let's start from the inside. Let us have, for simplicity,
struct Inner { vector<int> data; };
Add to it the functions of reading and writing to the file. The main thing - they must be consistent and write and read one format. For example:
struct Inner { vector<int> data; ifstream& read(ifstream& in) { data.clear(); size_t sz; in.read((char*)&sz,sizeof(sz)); data.resize(sz); in.read((char*)&data[0],sizeof(sz)); } ofstream& write(ofstream& out) { size_t sz = data.size(); out.write((char*)&sz,sizeof(sz)); out.write((char*)&data[0],sizeof(int)*sz); return out; } };
And may we now have
struct Outer { vector<Inner> data; };
Let's write exactly the same functions, only now when we write the vector, we will write the elements separately, one by one, without worrying about how this is done - the elements themselves will do this:
struct Outer { vector<Inner> data; ifstream& read(ifstream& in) { data.clear(); size_t sz; in.read((char*)&sz,sizeof(sz)); for(int i = 0; i < sz; ++i) { Inner iobj; iobj.read(in); data.push_back(iobj); } return in; } ofstream& write(ofstream& out) { size_t sz = data.size(); out.write((char*)&sz,sizeof(sz)); for(int i = 0; i < sz; ++i) { Inner& iobj = data[i]; iobj.write(out); } return out; } };
Imagine that we also have a char* field, a pointer to a string. We will add its record-reading:
struct Outer { vector<Inner> data; char * s; ifstream& read(ifstream& in) { data.clear(); size_t sz; in.read((char*)&sz,sizeof(sz)); for(int i = 0; i < sz; ++i) { Inner iobj; iobj.read(in); data.push_back(iobj); } in.read((char*)&sz,sizeof(sz)); delete[] s; s = new char[sz]; in.read(s,sz); return in; } ofstream& write(ofstream& out) { size_t sz = data.size(); out.write((char*)&sz,sizeof(sz)); for(int i = 0; i < sz; ++i) { Inner& iobj = data[i]; iobj.write(out); } sz = strlen(s)+1; out.write((char*)&sz,sizeof(sz)); out.write(s,sz); return out; } };
And so - for all fields, and if the fields are complex - their classes, then it is better to deal with them yourself ...
Write a read-write for
struct Envelope { vector<Outer> data; };
Can you do it yourself now? :)