Topic: static member initialization with templates


Author: Srinivas Vobilisetti <Srinivas.Vobilisetti@mci.com>
Date: 1997/12/02
Raw View
Bill Gibbons wrote:
>
> In article <347C35DD.2434@smarts.com>, Jerry Leichter
> <leichter@smarts.com> wrote:
>
> > There was a recent discussion of the continuing need for a definition -
> > even, in the new standard, one without the value being given - of static
> > class members.
> >
> > Consider now the following:
> >
> > template <class T>
> > class myClass
> > {       static  T*      root;
> >         ...
> > };
> >
> > (I want all the myClass<T>'s to be linked together so I can enumerate
> > them all.  This is just an example - there are other uses for the same
> > kind of thing.)
> >
> > This looks fine, but in practice makes myClass very hard to use:  For
> > every type Type for which myClass<Type> is instantiated, somewhere there
> > has to appear a:
> >
> > Type* myClass<Type>::root = 0;
> >
> > There's usually no reasonable place to put this, since no one module has
> > clear responsibility for any particular myClass<T>.
> >
> > Have I missed some trick for doing this?
>
> It isn't a trick.  You just have to define the template for the static
> data member, just as for a member function, as in:
>
>   template <class T> T* myClass<T>::root = 0;
>
> The implementation must automatically instantiate a single copy of the
> definition if the member is used, just as for member functions.

Also, if the definition of a static data member of template class is
placed in a seperate source (NOT header) file, we need to specify
keyword 'export' along with its definition like we do for a template
function.

example (consider the template class definition in this thread):

export template <class T> T* myClass<T>::root = 0;


Srinivas
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jerry Leichter <leichter@smarts.com>
Date: 1997/11/27
Raw View
There was a recent discussion of the continuing need for a definition -
even, in the new standard, one without the value being given - of static
class members.

Consider now the following:

template <class T>
class myClass
{ static T* root;
 ...
};

(I want all the myClass<T>'s to be linked together so I can enumerate
them all.  This is just an example - there are other uses for the same
kind of thing.)

This looks fine, but in practice makes myClass very hard to use:  For
every type Type for which myClass<Type> is instantiated, somewhere there
has to appear a:

Type* myClass<Type>::root = 0;

There's usually no reasonable place to put this, since no one module has
clear responsibility for any particular myClass<T>.

Have I missed some trick for doing this?
       -- Jerry
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bill@gibbons.org (Bill Gibbons)
Date: 1997/11/27
Raw View
In article <347C35DD.2434@smarts.com>, Jerry Leichter
<leichter@smarts.com> wrote:

> There was a recent discussion of the continuing need for a definition -
> even, in the new standard, one without the value being given - of static
> class members.
>
> Consider now the following:
>
> template <class T>
> class myClass
> {       static  T*      root;
>         ...
> };
>
> (I want all the myClass<T>'s to be linked together so I can enumerate
> them all.  This is just an example - there are other uses for the same
> kind of thing.)
>
> This looks fine, but in practice makes myClass very hard to use:  For
> every type Type for which myClass<Type> is instantiated, somewhere there
> has to appear a:
>
> Type* myClass<Type>::root = 0;
>
> There's usually no reasonable place to put this, since no one module has
> clear responsibility for any particular myClass<T>.
>
> Have I missed some trick for doing this?

It isn't a trick.  You just have to define the template for the static
data member, just as for a member function, as in:

  template <class T> T* myClass<T>::root = 0;

The implementation must automatically instantiate a single copy of the
definition if the member is used, just as for member functions.

(If there is no use of the static data member for a given (implicit or
explicit) specialization of the class template, then the static data
member is not instantiated, and any side effects of its initialization
will not occur.)

The definition of the static data member *template* can appear in a
header file, e.g. right after the class template.  Or, as with the
definition of a function template or member function of a class
template, it can appear in some non-header file.  (Assuming that
the implementation correctly handles the template compilation model.)

-- Bill Gibbons
   bill@gibbons.org
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/29
Raw View
Jerry Leichter wrote:
>
> Consider now the following:
>
> template <class T>
> class myClass
> {       static  T*      root;
>         ...
> };
>
> (I want all the myClass<T>'s to be linked together so I can enumerate
> them all.  This is just an example - there are other uses for the same
> kind of thing.)
>
> This looks fine, but in practice makes myClass very hard to use:  For
> every type Type for which myClass<Type> is instantiated, somewhere there
> has to appear a:
>
> Type* myClass<Type>::root = 0;
>
> There's usually no reasonable place to put this, since no one module has
> clear responsibility for any particular myClass<T>.

The current standard allows you to put the constant definition inside the class
definition, but not all compilers handle that yet. However, I've done exactly
this sort of thing, and I find that the module that the constant definition
belongs in is usually the module that contains the implementation of type T.
This is reasonable because there is no way to guarantee that all T's will be
included in the enumeration list without building the knowledge of your myClass
template into that particular module anyway.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]