From: Thomas Maeder on
magiceye <magiceye(a)163.com> writes:

> struct A
> {
> string sa;
> float na;
> };
> struct B
> {
> vector<A> vb;
> };
> struct C
> {
> string sc;
> B vc;
> };
>
> friend std::istream& operator>>(std::istream& is, B& m)
> {
> std::copy(std::istream_iterator<B>(is),
> std::istream_iterator<B>(),
> std::back_inserter(m.vb));

Does this even compile? m.vb is of type std::vector<A>, not
std::vector<B>.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Martin Bonner on
On Dec 19, 6:54 am, magiceye <magic...(a)163.com> wrote:
> I'm trying to serialize a custom class C's vector using stl. C's
> definition is:
> struct A
> {
> string sa;
> float na;};
>
> struct B
> {
> vector<A> vb;};
>
> struct C
> {
> string sc;
> B vc;};
>
[snip]
> However single C's object can be
> read completely, but for container vector<C>
[it fails]

Consider a file which contain
"c[0].sc"
"c[0].vc.vb[0].sa"
-1
"c[1].sc"
"c[1].vc.vb[0].sa"
-2

Ie, you have an array of two C objects, and each of them contain one A
object.

The problem is that when you come to serialize in the first C object
(and hence the first B object), it will try and read the string I have
shown as "c[1].sc" as being the "sa" value for a second A value. It
will then try and read "na" (and fail because the stream contains a
string).

The solution is that when you save the vector of A in B::operater >>
you first need to write out the count, and then in B::operator << only
try to read in that many A objects.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bart van Ingen Schenau on
magiceye wrote:

> I'm trying to serialize a custom class C's vector using stl. C's
> definition is:
> struct A
> {
> string sa;
> float na;
> };
> struct B
> {
> vector<A> vb;
> };
> struct C
> {
> string sc;
> B vc;
> };
> I implement operator<< and operator>> for A,B,C. operator<<()s are
> work fine, but operator>> for B has a problem:
> friend std::istream& operator>>(std::istream& is, B& m)
> {
> std::copy(std::istream_iterator<B>(is),
> std::istream_iterator<B>(), std::back_inserter(m.vb));
> is.tellg(); // return -1
> return is;
> }
> why is stream returns its pos -1?

That indicates that an error has occurred (the fail-bit on the stream
has been set).
This could be caused by an attempt to read past EOF, or because the data
did not match the required format.

> However single C's object can be
> read completely, but for container vector<C>, the -1 return will cause
> fail in next step reading.
> B's operator<<:
> friend std::ostream& operator<<(std::ostream& os, const B& m)
> {
> std::copy(m.vb.begin(), m.vb.end(), std::ostream_iterator<B>(os,
> "\n"));
> return os;
> }
>
You have a very nasty conceptual problem in your B::operator<<() and
B::operator>>().
The problem is that B::operator<<() writes an unspecified amount of data
to the stream, without any indication of how much data there is or an
end-of-data marker.
This makes it impossible for B::operator>>() to know when to stop
reading from the stream.
The easiest solution is to write a count of the number of elements in
the vector before the vector contents themselves.

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: magiceye on
Thanks for your replies. I thought "\n" can be the indicator because
the output file has form like this:

C.sc
A.sa
A.na

A.sa
A.na


C.sc
A.sa
A.na

so I thought one "\n" is delimiter of A's obejct, two continuous "\n"
is delimiter of C's object. But simple form STL utilities can't do
this automatically. And I try to use boost to serialize vector<C>, the
output files indeed contain many counts.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 | 
Pages: 1
Prev: LinkedHashMap in C++
Next: Namespace vs. isnan