Hi Christoph, > I tried to use a compiled operator<<(ostream,A<T>) in ROOT's interactive > mode. It was not obvious to me whether there is a suitable LinkDef > entry. I get this running without any hacks (like friend declarations) by a) providing a declaration of the instantiation which is parsed by CINT std::ostream& operator<<(std::ostream& os, const A<type>&); b) providing an entry of the instantiated operator in LinkDef.hh: #pragma link C++ class A<type>; #pragma link C++ function operator<<(std::ostream&, const A<type>&); I use a shell script which generates these statements. This makes it easy to add new template instantiations to CINT. The above solution works for ROOT versions 2.24.05 and 2.25.03, I have not tried with 3.01 up to now. Goodbye, Thorsten ---------------------------------------------------- Dr. Thorsten Glebe <Thorsten.Glebe@mpi-hd.mpg.de> Max-Planck-Institut fuer Kernphysik Saupfercheckweg 1 Tel: 06221/516-631 D-69117 Heidelberg Fax: 06221/516-603 ---------------------------------------------------- On Fri, 12 Jan 2001, Christoph Borgmeier wrote: > Hello, > > I just managed to put some of my very old problems into a small > demonstration program (ROOT 3.01). I would be very glad, if I got > answers or comments on as many of them as possible. The problems are > marked with `***' below. > > Here is an example: > ------------------------------- A.h ------------------------------ > #include <iostream> > > template <class T> > class A > { > public: > void print(std::ostream& os) const { os << '(' << T(65) << ')'; } > }; > > template <class T> > std::ostream& operator<<(std::ostream& os, const A<T>& a) > { > a.print(os); > return os; > } > ------------------------------------------------------------------- > > (LinkDef.h contains > #pragma link C++ class A<int>; > #pragma link C++ class A<char>; > ) > > *** The only way I found to ask rootcint to create the dictionary for > operator<< was to add a superfluous friend declaration: > > ----- in A.h inside template<class T> class A --------------------- > friend std::ostream& operator<< > #ifndef __CINT__ > <> > #endif > (std::ostream&, const A<T>&); > ------------------------------------------------------------------- > > *** [Reason for #ifdef __CINT__: the correct <> version lets rootcint > create invalid code.] > > With this hack(?), the operators are created correctly. > > But both of my recent projects had declarations which caused rootcint to > instantiate the templates too early (i.e. before reading LinkDef.h?): If > I add > > -----in A.h after template<class T> class A {...};----------------- > A<int> dummy(); > ------------------------------------------------------------------- > > CINT forgets to create the code for operator<<(ostream&,A<int>). This is > obviously due to the `instant' instantiation on reading the declaration > of dummy (visible with the trace option). > > *** Is there a way to influence CINT's behaviour? My real project > suffers even more because some return values, parameters, or pointers > which cause the instantiation, can only work on forward declarations > (leads to cyclic dependencies of CINT's template instantiations). > > Thanks your patience and in advance for any comment, > Christoph > > > P.S. A.h and LinkDef.h are attached to this message. The rootcint call > is > rootcint -f out.cxx -c -T A.h LinkDef.h > > > -- > Christoph Borgmeier <borg@ifh.de> > Address: Humboldt University, Institute for Physics > Invalidenstr. 110, D-10115 Berlin, Germany > Phone: +49(30)2093 7816 Fax: +49(30)2093 7642
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:33 MET