Hi Andre,
You do not have to modify rootcint to get what you want. Proceed as
follow:
- in LinkDef.h select option -
#pragma link C++ class MyClass-;
- In your member declaration use the "!" to declare it non persistent
vector<vector<Double_t> > myVector; //!
- The default Streamer function for MyClass is:
void MyClass::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
MyClass::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
} else {
MyClass::Class()->WriteBuffer(R__b,this);
}
}
- Extend this Streamer function Streamer function with the code
necessary to Stream the vector
void MyClass::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
MyClass::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
//add code to read the vector
} else {
MyClass::Class()->WriteBuffer(R__b,this);
//add the code to write the vector
}
}
With STL, one can build quickly very complex constructs. Currently
the automatic I/O supports only one level of arguments.
Things such as <vector<vector<basic type > > could be added to the STL
ROOT parser.
Rene Brun
On Fri, 10 Aug 2001, Andre Holzner wrote:
> Dear rooters,
>
> I'm facing the problem that I want to have a
> data member vector<vector<Double_t> >
> in one of my classes which I'd like to write to a root file.
>
> While I could write my own streamer from scratch or
> start from the generated streamer,
> I'd like to profit from rootcint's ability to generate
> the bulk of the streamer code for me (e.g. also when
> I add new fields to the class)
> and I'd like only to implement the streaming for
> these 'problematic' data types.
>
> Looking at an example streamer:
>
> void MyClass::Streamer(TBuffer &R__b)
> {
> // Stream an object of class MyClass.
>
> UInt_t R__s, R__c;
> if (R__b.IsReading()) {
> Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
> TNamed::Streamer(R__b);
> R__b >> a;
> R__b >> b;
> ...
> R__b.CheckByteCount(R__s, R__c, MyClass::IsA());
> } else {
> R__c = R__b.WriteVersion(MyClass::IsA(), kTRUE);
> TNamed::Streamer(R__b);
> R__b << a;
> R__b << b;
> ...
> R__b.SetByteCount(R__c, kTRUE);
> }
> }
>
> it looks to me that it should be possible e.g.
> to call my own function after calling the automatically
> streamer method. This own function streams then out
> the additional fields. The same could be done when reading
> an object back from a TBuffer.
>
> So my questions:
>
> - What do you think about giving rootcint another
> option to call the Streamer differently ?
> (in that case, one could implement a method
> MyClass::Streamer which first calls
> MyClass::GeneratedStreamer and then handles the
> other data fields). [I'd volunteer to try to
> implement such an option into rootcint]
>
> - What about giving TObject an additional virtual
> method PostStreamer(TBuffer &) which is called
> at the end of Streamer() ?
> (one might be concerned about slightly lower
> performance..)
>
> Or is it already possible to implement a 'private
> additional streamer' ? (from the Root User's guide
> p.193, this is not clear to me)
>
>
> best regards,
>
> André
> --
> ------------------+----------------------------------
> Andre Holzner | +41 22 76 76750
> Bureau 32 2-C13 | Building 32
> CERN | Office 2-C13
> CH-1211 Geneve 23 | http://wwweth.cern.ch/~holzner/
>
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:57 MET