Re: [ROOT] ostream << on template class (and related things)

From: thorsten glebe (glebe@mpi-hd.mpg.de)
Date: Sun Jan 14 2001 - 23:41:32 MET


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