Subject: Re: c++ templates
To: Patrick Welche <prlw1@cam.ac.uk>
From: Todd Vierling <tv@pobox.com>
List: netbsd-help
Date: 09/18/1998 13:41:35
[Note: tech-toolchain is the best mailing list for this, so I'm moving the
thread there]

On Fri, 18 Sep 1998, Patrick Welche wrote:

: gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
: 
: as per -current, I am trying to use a template:
: 
: export template <class monadType>
: void stamp(monadType& a)
: {
: ...
: 
: and get
: 
: syntax error before `template'
: 
: presumably from the "export". I am new to the c++ game, but thought I
: had to "export" a template so that it may be instantiated in another
: .cc text file. Is this not implemented in egcs (ie., I have to put the
: code for the template in a header file) or am I missing something?

"export" doesn't work on egcs-1.1.  With that said (and as I'm not sure
exactly how "export" works, coming from a reader of Stroustrup 3ed which
doesn't define "export"--that's one of the last additions to the draft
before it was standardized):

You can define templates in one of two ways.  First, the basic
class-and-inline-methods in a header file.

template <class C>
class foo {
	C c;
public:
	C& get_ref() { return c; }
};

This is all inline, so it is used whenever instantiated (explicitly or
otherwise) and you never have to write an implementation for it.

The other major way is to give a class with an external method which must be
defined as an inline in the header or otherwise defined for all
specializations:

--- header file:
template <class C>
class foo {
	C c;
public:
	C& get_ref();
};

--- inline in header file:
template <class C>
C& foo<C>::get_ref() { return c; }

--- implementation file (if the inline doesn't exist) - explicitly specialized:
template <double>
double& foo<double>::get_ref() { return c; }

That's basically all that the standard allows without the use of export. G++
(and egcs) gives you one more way, which can save code space.  If you define
all the template as inline methods (first style above) you can add an
implementation backing file that will collimate the otherwise local statics
for functions left non-inlined with:

--- header file (note you must make it specialized, and the class must be
    defined in the header above this construct):
#ifdef __GNUC__
extern template class foo<double>;
#endif

--- implementation file - explicitly instantiates the whole specialized class:
template class foo<double>;

This is good for small, overly used classes such as "string" (actually,
"basic_string<char>").

That reminds me; I should probably add a couple of these to the libstdc++
includes, because some basic types are already instantiated in libstdc++.
For some reason, this isn't done in the libstdc++ includes as shipped.

-- 
-- Todd Vierling (Personal tv@pobox.com; Bus. todd_vierling@xn.xerox.com)