Topic: Template Instantiation


Author: "Michael Rice" <mpr@absoft.com>
Date: 1995/10/29
Raw View
I have a question concerning class template instantitation, as described
in section 14.3.2 on the Sep 1995 WP.

Paragraph 6 says:

An implementation shall not instantiate a function, nonvirtual member
function, class or member class that does not require instantiation.

The section goes on the give examples of a few cases that do require
instantiation and a few that do not require instantiation.  It seems
to me, that it should state EXACTLY when they are required and it
doesn't seem to in this section.  Does it anywhere?  If it is not
stated implementations could decide anything in a requirement. Couldn't
they?  Take this example:

struct incomplete;

template<class T>
struct reverse_iterator {
  reverse_iterator ( );
  incomplete i;
};

typedef reverse_iterator<long> reverse_iterator1 ;

template < class T >
struct vector {
  vector ( );
};

main()
{
  vector < int > i ;
  return 0;
}

If an implementation decides the typedef above makes the instantiation
of reverse_iterator<long> required this code is ill-formed as the struct
incomplete is incomplete.

On the other hand, the implementation could say it is not required due to
this typedef (which seems correct to me.)  Now the code is well formed?

What about this:

template<class T>
struct reverse_iterator {
  reverse_iterator ( );
};

typedef reverse_iterator<long> reverse_iterator1 ;

template < class T >
struct vector {
  reverse_iterator1 rbegin ( ) { return reverse_iterator1 ( ) ; }
  vector ( );
};

main()
{
  vector < int > i ;
  return 0;
}

Is reverse_iterator<long> required to be instantiated here even though
the inline function is never called?

Can someone point me in the right direction on when instantiations are
required?  Thanks.

--
Mike Rice                                                   Absoft Corporation
mpr@absoft.com                                                  (810) 853-0050
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1995/10/30
Raw View
>>>>> "MR" == Michael Rice <mpr@absoft.com> writes:
MR> I have a question concerning class template instantitation, as described
MR> in section 14.3.2 on the Sep 1995 WP.
MR> Paragraph 6 says:
MR> An implementation shall not instantiate a function, nonvirtual member
MR> function, class or member class that does not require instantiation.
MR> The section goes on the give examples of a few cases that do require
MR> instantiation and a few that do not require instantiation.  It seems
MR> to me, that it should state EXACTLY when they are required and it
MR> doesn't seem to in this section.  Does it anywhere?  If it is not

I believe it is implicit in the semantic descriptions throughout the DWP.
For functions (member or not), they should only be instantiated if they
are called. The only exception are virtual functions: they can be
instantiated if the class to which they belong is instantiated.

Classes and member classes should be instantiated only if their size
or at least part of their layout is needed. If only their name is needed,
no instantiation should occur.

MR> stated implementations could decide anything in a requirement. Couldn't
MR> they?  Take this example:

MR> struct incomplete;

MR> template<class T>
MR> struct reverse_iterator {
MR>   reverse_iterator ( );
MR>   incomplete i;
MR> };

MR> typedef reverse_iterator<long> reverse_iterator1 ;

MR> template < class T >
MR> struct vector {
MR>   vector ( );
MR> };

MR> main()
MR> {
MR>   vector < int > i ;
MR>   return 0;
MR> }

MR> If an implementation decides the typedef above makes the instantiation
MR> of reverse_iterator<long> required this code is ill-formed as the struct
MR> incomplete is incomplete.

MR> On the other hand, the implementation could say it is not required due to
MR> this typedef (which seems correct to me.)  Now the code is well formed?

Indeed, only the ``name'' of the type is needed: that does not require
instantiation. The fact that some compilers (unconformingly) do instantiate
in this case, and that this was a fairly popular method of explicitly
invoking instantiation is somewhat misleading.

MR> What about this:

MR> template<class T>
MR> struct reverse_iterator {
MR>   reverse_iterator ( );
MR> };

MR> typedef reverse_iterator<long> reverse_iterator1 ;

MR> template < class T >
MR> struct vector {
MR>   reverse_iterator1 rbegin ( ) { return reverse_iterator1 ( ) ; }
MR>   vector ( );
MR> };

MR> main()
MR> {
MR>   vector < int > i ;
MR>   return 0;
MR> }

MR> Is reverse_iterator<long> required to be instantiated here even though
MR> the inline function is never called?
[...]
No, it should not be instantiated (unless it were virtual). Many compilers
are sloppy about this, unfortunately.

 Daveed
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: "Michael Rice" <mpr@absoft.com>
Date: 1995/10/30
Raw View
> I believe it is implicit in the semantic descriptions throughout the DWP.
> For functions (member or not), they should only be instantiated if they
> are called. The only exception are virtual functions: they can be
> instantiated if the class to which they belong is instantiated.
>
> Classes and member classes should be instantiated only if their size
> or at least part of their layout is needed. If only their name is needed,
> no instantiation should occur.
>

What about the use of a typedef name from the class.  No size or layout
is needed.   Example:

struct incomplete;

template <class T>
struct allocator {
public :
  typedef T* pointer;
  incomplete i;
};

template <class T>
struct vector {
  allocator<T>::pointer start;
  vector();
};

main()
{
  vector<int> v;
  return 0;
}

Then this should be well-formed.  While specializing vector<int> we have
to determine the member start's type.  We don't need to specialize
allocator<int> to do that.  So we can use allocator<int>::pointer, and
allocator<anything>::pointer without ever specializing the class.  Is that
the intent?  Is that desirable?

--
Mike Rice                                                   Absoft Corporation
mpr@absoft.com                                                  (810) 853-0050

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]






Author: jason@cygnus.com (Jason Merrill)
Date: 1995/10/30
Raw View
>>>>> David Vandevoorde <vandevod@cs.rpi.edu> writes:

> I believe it is implicit in the semantic descriptions throughout the DWP.
> For functions (member or not), they should only be instantiated if they
> are called. The only exception are virtual functions: they can be
> instantiated if the class to which they belong is instantiated.

What if their address is taken?  What if they are called in a sizeof
expression?  What about static data members?

Jason
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Sean A Corfield <sean@corf.demon.co.uk>
Date: 1995/10/31
Raw View
In article <VANDEVOD.95Oct30181524@avs.cs.rpi.edu>,
vandevod@cs.rpi.edu (David Vandevoorde) wrote:

|> MR> What about the use of a typedef name from the class.  No size or
|> MR> layout is needed.  Example:
|> [example elided ...]
|>
|> Good point. I thought it shouldn't (necessarily) require instantiation
|> of the typedef-enclosing class, but my favo(u)rite compiler says
|> otherwise (with your particular example)... and its designers are very
|> knowledgeable in this area.
|>
|> Anyone care to comment?

I'd go with your compiler designers on this one: to get the type of a class
member, you'd have to instantiate the class. There's a paper being written
on this topic (when types are required to be complete) which should be
voted on in March '96. Classes are required to be instantiated exactly when
the class type is required to be complete (plus a couple of other, explicit
uses such as in pointer to class casts). If the WP isn't clear enough on
this, well, we're still working on it!



--
         You must be out of your brilliant mind - Furniture
                 http://uptown.turnpike.net/~scorf


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]