RE: [ROOT] root(cint) and template

From: Philippe Canal (pcanal@fnal.gov)
Date: Fri May 11 2001 - 21:25:44 MEST


Hi Jacek,

I looked at your code.  The failure is due to the fact that you are trying
to use
ClassDefT on specialized classes.  In order for your example to work
you would need a version of the ClassImpT that specialize the member
function rather
than declare/implement their generic version.

Philippe.

PS. Here is a possible implementation:

#define _ClassImpTS_(name,Tmpl) \
   TClass *name<Tmpl>::Class() \
      { if (!fgIsA) name<Tmpl>::Dictionary(); return fgIsA; } \
   const char *name<Tmpl>::ImplFileName() \
      { return __FILE__; } \
   int name<Tmpl>::ImplFileLine() { return __LINE__; } \
   TClass *name<Tmpl>::fgIsA = 0;

#define ClassImpTS(name,Tmpl) \
   void name<Tmpl>::Dictionary() { \
      fgIsA = CreateClass(Class_Name(),   Class_Version(), \
                          DeclFileName(), ImplFileName(), \
                          DeclFileLine(), ImplFileLine()); \
   } \
   _ClassImpT_(name,Tmpl)


PPS. Here is a simple example showing what basically happen in your case.

> g++ -g t01.C
/tmp/cc2IBnV8.o: In function `SimpleTmpl<double>::SimpleTmpl(double)':
/cdf/scratch/pcanal/test/Jacek/t01/Complex/t01.C:12: undefined reference to
`SimpleTmpl<double>::GetVal(void)'
collect2: ld returned 1 exit status

// file t01.C
template <class T> class SimpleTmpl {
 public:
  T val;
  SimpleTmpl(T in) : val(in) {};
  T GetVal();
};

// The following line is an 'equivalent' to the content
// of ClassImpT
template <class T> T SimpleTmpl<T>::GetVal() { return val; };

class SimpleTmpl<double> {
 public:
  double val;
  SimpleTmpl(double in) : val(in) {};
  double GetVal();
};

int main() {
  SimpleTmpl<int> i(2);
  SimpleTmpl<double> d(3.2);
  int a = i.GetVal();
  double b = d.GetVal();

  return a;

}-----Original Message-----
From: owner-roottalk@pcroot.cern.ch
[mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Jacek M. Holeczek
Sent: Friday, May 11, 2001 11:56 AM
To: Philippe Canal
Cc: roottalk@pcroot.cern.ch
Subject: RE: [ROOT] root(cint) and template


Hi,
Something got shorted in my mind ... and I can't recall how to make my
nice "template <class _FLT> class Complex" visible in ROOT (from a shared
library). I don't want to inherit from TObject, nor to use ClassDefT(2) as
they both add private data members.
So, how should the LinkDef look like ?
Thanks in advance,
Jacek.
P.S. Anyhow, I tried to inherit from TObject and use ClassDefT(2) and I got
:
----------------------------------------------------------------------------
-
[GSL]$ g++ -g -O2 -fPIC -DD -DALL -DROOT -I$ROOTSYS/include -c Cinst.cxx -o
DComplex.o
[GSL]$ g++ -g -O2 -fPIC -DF -DALL -DROOT -I$ROOTSYS/include -c Cinst.cxx -o
FComplex.o
[GSL]$ g++ -g -O2 -fPIC -DLD -DALL -DROOT -I$ROOTSYS/include -c Cinst.cxx -o
LDComplex.o
[GSL]$ rootcint -f G__Complex.cxx -DROOT Complex ComplexLinkDef.h
[GSL]$ g++ -g -O2 -fPIC -DROOT -I$ROOTSYS/include -c G__Complex.cxx
[GSL]$ g++ -g -O2 -fPIC -DROOT -I$ROOTSYS/include -shared -o Complex.so
FComplex.o DComplex.o G__Complex.o
[GSL]$ root
  *******************************************
  *                                         *
  *        W E L C O M E  to  R O O T       *
  *                                         *
  *   Version   3.00/06     12 March 2001   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

FreeType Engine v1.x used to render TrueType fonts.
Compiled with thread support.

CINT/ROOT C/C++ Interpreter version 5.14.79, Feb 24 2001
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .L ./Complex.so
dlopen error: /.automount/p2a00/root/h/holeczek/src/root/GSL/././Complex.so:
undefined symbol: __vt_t7Complex1Zr
Load Error: Failed to load Dynamic link library
/.automount/p2a00/root/h/holeczek/src/root/GSL/././Complex.so
*** Interpreter error recovered ***
root [1] .q
----------------------------------------------------------------------------
-
The ComplexLinkDef.h was just :
----------------------------------------------------------------------------
-
#ifdef __CINT__
#pragma link off all typedefs;
#pragma link off all globals;
#pragma link off all functions;
#pragma link off all classes;

#pragma link C++ class Complex<float>;
#pragma link C++ class Complex<double>;
#if 0 // CINT error in sizeof(long double)
#pragma link C++ class Complex<long double>;
#endif

#endif
----------------------------------------------------------------------------
-



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:45 MET