Topic: Instantiating members of templates.


Author: miker3@ix.netcom.com (Mike Rubenstein)
Date: 1996/11/14
Raw View
fwai@armltd.co.uk (Francis Wai) wrote:

> miker3@ix.netcom.com (Mike Rubenstein) writes:
>
> >What is the intent of the following statement in 14.3.2:
>
> > An implementation shall not instantiate a function, nonvirtual
> > member function, class or member class that does not require
> > instantiation.
>
> >Am I correct in believing that this would make the following code
> >legal?
>
> > class A {
> > };
>
> > template<class T> B {
> >   public:
> >     void f(const T& x) { x.foo(); }
> > };
>
> > int main()
> > {
> >   B<A> b;
> >   return 0;
> > }
>
> >My reasoning is that isnce B<A>::f is never called, it will not be
> >instantiated and A::foo() need not be defined.
>
> No, this would not be legal. The crux of the matter is that 'x' is not
> regarded as a class/struct/union object by the compiler. Quoting from
> a DWP 14.7 clause 4,
>
>   4 A template-parameter that could be interpreted as either an parameter-
>   declaration or a type-parameter (because its identifier is the name of
>   an  already existing class) is taken as a type-parameter.  A template-
>   parameter hides a variable, type, constant, etc. of the same  name  in
>   the enclosing scope.  [Example:
>           class T { /* ... */ };
>           int i;
>
>           template<class T, T i> void f(T t)
>           {
>                   T t1 = i;      // template-arguments T and i
>                   ::T t2 = ::i;  // globals T and i
>           }
>   Here,  the  template  f  has a type-parameter called T, rather than an
>   unnamed non-type parameter of class T.  ] There is no semantic differ-
>   ence between class and typename in a template-parameter.
>
> Note the last sentence in the above paragraph.
>
> Again, quoting from D&E 15.3,
>
>   The keyword _class_ is used to indicate arguments of type _type_ partly
>   because it appears to be an appropriate word, partly because it saves
>   introducing a new keyword. In this context, _class_ means "any type" and
>   not just "some user-defined type".
>
> Quite a number of people have fallen into the trap believing the obvious.
> This is unfortunate.

Huh?  T is not the name of an already existing class.  It can only be
interpretted as the template parameter.

Michael M Rubenstein
---
[ 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: fwai@armltd.co.uk (Francis Wai)
Date: 1996/11/14
Raw View
miker3@ix.netcom.com (Mike Rubenstein) writes:

>Huh?  T is not the name of an already existing class.  It can only be
>interpretted as the template parameter.

More appropriately it can only be interpreted a name for an unknown type much
as 'typename' which introduces a type name but does not say what it is.

--Francis
---
[ 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: fwai@armltd.co.uk (Francis Wai)
Date: 1996/11/14
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

>fwai@armltd.co.uk (Francis Wai) writes:

>>miker3@ix.netcom.com (Mike Rubenstein) writes:
>>
>>>What is the intent of the following statement in 14.3.2:
>>
>>> An implementation shall not instantiate a function, nonvirtual
>>> member function, class or member class that does not require
>>> instantiation.
>>
>>>Am I correct in believing that this would make the following code
>>>legal?
>>
>>> class A {
>>> };
>>
>>> template<class T> B {
>>>   public:
>>>     void f(const T& x) { x.foo(); }
>>> };
>>
>>> int main()
>>> {
>>>   B<A> b;
>>>   return 0;
>>> }
>>
>>>My reasoning is that isnce B<A>::f is never called, it will not be
>>>instantiated and A::foo() need not be defined.
>>
>>No, this would not be legal.

>I'm pretty sure you're wrong -- I think the example is legal.

>>The crux of the matter is that 'x' is not
>>regarded as a class/struct/union object by the compiler.

>Even if it were B<int>, it would still be legal.  Semantic checking is
>not performed until the template is instantiated.  See 14.6/4:

OK, I buy. The compiler should not be bias since 'T' can name
any type.

However, the statement about deferring semantic checking until
instantiation is not entirely accurate. 14.2.2 gave an example,


 [Example:
          void g(double);
          void h();

          template<class T> class Z {
          public:
                  void f() {
                          g(1); // calls g(double)
                          h++;  // error: cannot increment function
                  }
          };

          void g(int); // not in scope at the point of the template
                       // definition, not considered for the call g(1)
    --end  example] [Note:  a  template definition behaves exactly like
  other definitions. ]

This seems to say do all of syntactic analysis and as much semantic
analysis as possibly can. Hmmmm, ....

--Francis
---
[ 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: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/14
Raw View
>>>>> "FW" == Francis Wai <fwai@armltd.co.uk> writes:

FW> fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
[...]
>> Even if it were B<int>, it would still be legal.  Semantic checking is
>> not performed until the template is instantiated.  See 14.6/4:

I think Fergus quoted a DWP passage saying that semantic checking
is not performed _if at least one valid instantiation exists_.

[...]
FW> However, the statement about deferring semantic checking until
FW> instantiation is not entirely accurate. 14.2.2 gave an example,


FW>  [Example:
FW>           void g(double);
FW>           void h();

FW>           template<class T> class Z {
FW>           public:
FW>                   void f() {
FW>                           g(1); // calls g(double)
FW>                           h++;  // error: cannot increment function
FW>                   }
FW>           };

FW>           void g(int); // not in scope at the point of the template
FW>                        // definition, not considered for the call g(1)
FW>     --end  example] [Note:  a  template definition behaves exactly like
FW>   other definitions. ]

FW> This seems to say do all of syntactic analysis and as much semantic
FW> analysis as possibly can. Hmmmm, ....

Note that there is no type T for which the above template is valid,
and hence (if my recollection is accurate) the error above exists
already at template definition time.

 Daveed
---
[ 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: fwai@armltd.co.uk (Francis Wai)
Date: 1996/11/14
Raw View
vandevod@cs.rpi.edu (David Vandevoorde) writes:

>>>>>> "FW" == Francis Wai <fwai@armltd.co.uk> writes:

>FW> However, the statement about deferring semantic checking until
>FW> instantiation is not entirely accurate. 14.2.2 gave an example,


>FW>  [Example:
>FW>           void g(double);
>FW>           void h();

>FW>           template<class T> class Z {
>FW>           public:
>FW>                   void f() {
>FW>                           g(1); // calls g(double)
>FW>                           h++;  // error: cannot increment function
>FW>                   }
>FW>           };

>FW>           void g(int); // not in scope at the point of the template
>FW>                        // definition, not considered for the call g(1)
>FW>     --end  example] [Note:  a  template definition behaves exactly like
>FW>   other definitions. ]

>FW> This seems to say do all of syntactic analysis and as much semantic
>FW> analysis as possibly can. Hmmmm, ....

>Note that there is no type T for which the above template is valid,
>and [stuff deleted]

Why?

I would have thought the opposite is true. The type argument in an
instantiation of 'Z' can be any type and the instantiation would be valid.
Have I read your statement correctly?

Also, suppose 'f' has a T& argument 'x' and its body contains an additional
expression, say, "x.foo();". Q: would there be a diagnostics for 'h++'?

--Francis
---
[ 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: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/14
Raw View
>>>>> "FW" == Francis Wai <fwai@armltd.co.uk> writes:
FW> vandevod@cs.rpi.edu (David Vandevoorde) writes:
FW> [Example:
FW> void g(double);
FW> void h();

FW> template<class T> class Z {
FW> public:
FW>    void f() {
FW>       g(1); // calls g(double)
FW>       h++;  // error: cannot increment function
FW>    }
FW> };
[...]
>> Note that there is no type T for which the above template is valid,
>> and [stuff deleted]

FW> Why?

Because whatever the type of T, the expression `h++;' is not valid.

[...]
FW> Also, suppose 'f' has a T& argument 'x' and its body contains an
FW> additional expression, say, "x.foo();". Q: would there be a
FW> diagnostics for 'h++'?

I believe the compiler would be allowed to generate a diagnostic at
template definition time. Either way, I don't think a diagnostic is
_required_ at that time; it could be delayed until instantiation/use
time (but I'm not sure).

 Daveed
---
[ 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: miker3@ix.netcom.com (Mike Rubenstein)
Date: 1996/11/13
Raw View
What is the intent of the following statement in 14.3.2:

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

Am I correct in believing that this would make the following code
legal?

 class A {
 };

 template<class T> B {
   public:
     void f(const T& x) { x.foo(); }
 };

 int main()
 {
   B<A> b;
   return 0;
 }

My reasoning is that isnce B<A>::f is never called, it will not be
instantiated and A::foo() need not be defined.

This came up in looking at the container classes.  These have
comparison operators (e.g., operator<) which, of course, depend on the
corresponding comparison operators for the contained objects.  Does
14.3.2 imply that if one never uses the comparison operator for the
container it need not be defined for the contained object?

Michael M Rubenstein
---
[ 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: fwai@armltd.co.uk (Francis Wai)
Date: 1996/11/13
Raw View
miker3@ix.netcom.com (Mike Rubenstein) writes:

>What is the intent of the following statement in 14.3.2:

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

>Am I correct in believing that this would make the following code
>legal?

> class A {
> };

> template<class T> B {
>   public:
>     void f(const T& x) { x.foo(); }
> };

> int main()
> {
>   B<A> b;
>   return 0;
> }

>My reasoning is that isnce B<A>::f is never called, it will not be
>instantiated and A::foo() need not be defined.

No, this would not be legal. The crux of the matter is that 'x' is not
regarded as a class/struct/union object by the compiler. Quoting from
a DWP 14.7 clause 4,

  4 A template-parameter that could be interpreted as either an parameter-
  declaration or a type-parameter (because its identifier is the name of
  an  already existing class) is taken as a type-parameter.  A template-
  parameter hides a variable, type, constant, etc. of the same  name  in
  the enclosing scope.  [Example:
          class T { /* ... */ };
          int i;

          template<class T, T i> void f(T t)
          {
                  T t1 = i;      // template-arguments T and i
                  ::T t2 = ::i;  // globals T and i
          }
  Here,  the  template  f  has a type-parameter called T, rather than an
  unnamed non-type parameter of class T.  ] There is no semantic differ-
  ence between class and typename in a template-parameter.

Note the last sentence in the above paragraph.

Again, quoting from D&E 15.3,

  The keyword _class_ is used to indicate arguments of type _type_ partly
  because it appears to be an appropriate word, partly because it saves
  introducing a new keyword. In this context, _class_ means "any type" and
  not just "some user-defined type".

Quite a number of people have fallen into the trap believing the obvious.
This is unfortunate.

--Francis
---
[ 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: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/13
Raw View
>>>>> "MR" == Mike Rubenstein <miker3@ix.netcom.com> writes:
MR> What is the intent of the following statement in 14.3.2:
MR>  An implementation shall not instantiate a function, nonvirtual
MR>  member function, class or member class that does not require
MR>  instantiation.

MR> Am I correct in believing that this would make the following code
MR> legal?
[...]

Yes, you are correct.

 Daveed
---
[ 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: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/11/13
Raw View
fwai@armltd.co.uk (Francis Wai) writes:

>miker3@ix.netcom.com (Mike Rubenstein) writes:
>
>>What is the intent of the following statement in 14.3.2:
>
>> An implementation shall not instantiate a function, nonvirtual
>> member function, class or member class that does not require
>> instantiation.
>
>>Am I correct in believing that this would make the following code
>>legal?
>
>> class A {
>> };
>
>> template<class T> B {
>>   public:
>>     void f(const T& x) { x.foo(); }
>> };
>
>> int main()
>> {
>>   B<A> b;
>>   return 0;
>> }
>
>>My reasoning is that isnce B<A>::f is never called, it will not be
>>instantiated and A::foo() need not be defined.
>
>No, this would not be legal.

I'm pretty sure you're wrong -- I think the example is legal.

>The crux of the matter is that 'x' is not
>regarded as a class/struct/union object by the compiler.

Even if it were B<int>, it would still be legal.  Semantic checking is
not performed until the template is instantiated.  See 14.6/4:

|  14.6  Name resolution                                       [temp.res]
|
| 4 ... No diagnostic shall be issued for a tem-
|   plate definition for which a valid specialization  can  be  generated.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ 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                             ]