Hi, As you noted the streamer automatically created by rootcint is forgetting to 'clean' the vector before reading the streamer. For greater flexibility a Streamer should not assume that the object it is reading is clean and should insure clean-up. (To allow loop like in the Y::Streamer). This problem should be fixed shortly in the cvs repository. Philippe. > -----Original Message----- > From: owner-roottalk@pcroot.cern.ch > [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Matevz Tadel > Sent: Tuesday, August 08, 2000 9:10 AM > To: roottalk@pcroot.cern.ch > Subject: [ROOT] streamers for nested stl containers > > > Hi, > > Imagine a situation: > > X.h <<fnord > #ifndef _x_h_ > #define _x_h_ > > #include <TNamed.h> > #include <vector> > #include <iostream> > > class X : public TNamed { > public: > vector<int> mV; > > X(const Text_t* n="x") : TNamed(n,0) {} > void Populate(Int_t M=3) { for(int i=0; i<M; i++) mV.push_back(i); } > void Spit() { > cout << GetName() <<": ["; > for(vector<int>::iterator i=mV.begin(); i!=mV.end(); i++) cout > <<*i<<" "; > cout <<"]\n"; > } > > ClassDef(X,1) > }; > > #endif > fnord > > Y.h << fnord > #ifndef _y_h_ > #define _y_h_ > > #include "X.h" > #include <TObject.h> > #include <vector> > > class Y : public TObject { > public: > vector<X> mX; > > void Populate(Int_t M=3) { > char a='A', n[2]; for(int i=0; i<M; i++,a++) { > sprintf(n,"%c",a); > X x(n); x.Populate(i+1); > mX.push_back(x); > } > } > void Spit() { for(vector<X>::iterator > i=mX.begin(); i!=mX.end(); i++) i->Spit(); } > ClassDef(Y,1) > }; > > #endif > fnord > > root session 1: > root [0] #include <vector> > root [1] gSystem->Load("libElDictos.so") > (int)0 > root [2] Y y > root [3] y.Populate() > root [4] y.Spit() > A: [0 ] > B: [0 1 ] > C: [0 1 2 ] > root [5] TFile f("xy.root","RECREATE") > root [6] y.Write("Y") > (Int_t)134 > root [7] f.Close() > root [8] .q > > root session 2: > root [0] #include <vector> > root [1] gSystem->Load("libElDictos.so") > (int)0 > root [2] TFile f("xy.root") > root [3] .ls > TFile** xy.root > TFile* xy.root > KEY: Y Y;1 > root [4] Y.Spit() > A: [0 ] > B: [0 0 1 ] > C: [0 0 1 0 1 2 ] > > Conclusion: > Reading of stl container fails, if its elements contain further stl > containers ... > eg: > // Stream an object of class Y. > if (R__b.IsReading()) { > Version_t R__v = R__b.ReadVersion(); if (R__v) { } > TObject::Streamer(R__b); > { > int R__i, R__n; > X R__t; //!! should be inside loop !! > R__b >> R__n; > for (R__i = 0; R__i < R__n; R__i++) { > R__t.Streamer(R__b); > mX.push_back(R__t); > } > } > } else { ... > > perhaps i live in a dream world, but i would expect the code with > declaration inside the loop consume the same number of constructors (due > to optimizations for a variable going out of scope copy constructor for > stl element is not called). In this case it has to be invoked anyway > ... we just gain one destruction (which isn't called if my dream > optimization really exists) > > huh ... back to my histograms ... > > cheers, > matevz > > -- > --------------------------------------------------- > Matevz Tadel, E-mail: Matevz.Tadel@ijs.si > Department of Experimental High Energy Physics F9 > Jozef Stefan Institute, Jamova 39, P.o.Box 3000 > SI-1001 Ljubljana, Slovenia > Tel.: +386-61-177-3674 Fax: +386-61-125-7074 > --------------------------------------------------- > >
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:31 MET