[ROOT] adding a class which includes STL

From: Bart Lode Frank VAN DE VYVER (Bart.Vandevyver@cern.ch)
Date: Wed Sep 04 2002 - 17:32:24 MEST


Hi,

I'm new to ROOT and going through the usual growing pains. What I would
like to do is to store STL containers of objects with references between
them, writing them from a C++ program and reading them interactively
into ROOT.

The simplest case works quite well. Running the following

class ClassB : public TObject {
  unsigned countB;
public:
  ClassB( unsigned countB =0 ) : countB(countB) {}
  unsigned          GetCountB() const { return countB; }
  ClassDef(ClassB,1)
};

(with a .cc with the ClassImp) I managed to write objects of type ClassB
to a ROOT tree, read them back in interactive root or simply instantiate
and manipulate objects of type ClassB in interactive ROOT.

1) STL containers of basic types
   +++++++++++++++++++++++++++++
Adding a data member of type vector<unsigned>, rootcint stumbles,
typically spitting out something along the lines of

Error: Function unsigned() is not defined in current scope 
FILE:/afs/cern.ch/sw/root/pro/@sys/root/cint/lib/prec_stl/vector
LINE:133

I've tried putting a 
#pragma link C++ class vector<unsigned>;
in the LinkDef.h but that doesn't change anything.

However, interactively a simple #include <vector.h> is clearly
sufficient to be able to instantiate vectors of unsigned and manipulate
them.

2) STL containers of classes
   +++++++++++++++++++++++++
As for simple types, instantiating and manipulating a vector of an
'added class' works in interactive ROOT.

However, for me it stops working the moment the STL container of the
added class is also present in my C++ program.

Suppose there is, in addition to ClassB, a class Unsigned

class Unsigned : public TObject {
private:
  unsigned value;
public:
  Unsigned( unsigned val =0 );
  operator unsigned() const { return value; }
  unsigned GetValue() const { return value; }
  ClassDef(Unsigned,1)
};

to avoid the fact that rootcint complains about vector<unsigned>. Now,
rootcint does not complain about a vector<Unsigned> in ClassB. Strangely
enoug, rootcint manifestly does not like to see "#pragma link C++ class
vector<Unsigned>;" (add any +,-,! you like, the result is the same) in
the LinkDef.h as that triggers the following error:

Class vector<Unsigned,__malloc_alloc_template<0> >: Streamer() not
declared
Class vector<Unsigned,__malloc_alloc_template<0> >: ShowMembers() not
declared
Class vector<Unsigned,__malloc_alloc_template<0> >: Class_Name() and
initialization object not declared

In any case, if I don't modify the LinkDef.h then rootcint does work.
However, having a vector<Unsigned> in ClassB makes all the difference
between the following lines working or not working in interactive ROOT:

  Unsigned num(20);
  vector<Unsigned> vecU;
  vecU.push_back(num);
  printf("vector of Unsigned first element %i\n",vecU[0].GetValue());

If Unsigned is in the DLL but no vector<Unsigned> is used in the DLL,
then interactive ROOT is happy about vector<Unsigned>. If it is used in
the DLL, then using vector<Unsigned> in interactive ROOT manages to
crash my session.

Thanks for any advice on how to do stuff like this,
Bart



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:07 MET