🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

7 total messages Started by Steve Clamage Mon, 21 Aug 1995 22:11
Re: Template instantiation question
#1782
Author: Steve Clamage
Date: Mon, 21 Aug 1995 22:11
54 lines
2658 bytes
In article 95Aug21100336@physics10.Berkeley.EDU, bmcphers@alias.com (Brent McPherson) writes:
>
>I have seen template classes that define methods that will only *work*
>if the instantiation type provides certain methods/functionality.
>
>ie.
>
>  template<class T>
>  class Foo {
>  public:
>     Foo (const T &t) : myT(T) {}
>     // etc...
>     int compare (const T &otherT) 
>     { 
>       return (myT < otherT ? -1 : myT > otherT ? 1 : 0);
>     }
>     // etc...
>  };
>
>In this example the "compare" method relies on the object of type T
>having comparison operators.
>
>Is it legal to allow Foo to be instantiated with an object that does
>not support comparison as long as the compare method is never called
>for that particular instantiation?

The draft standard, 14.3.2 Point of Instantiation [temp.point], says
the implementation shall not instantiate a class or function that does not
require instantiation. A non-virtual function that is never called and
never has its address taken does not require instantiation.

In your example, if you create a variable of type Foo<X>, where X is
some type, and never use the non-virtual compare function, that
function, Foo<X>::compare, should not be instantiated.

Details of template definition and instantiation have been modified or
clarified recently, and it will take a while for compilers to catch up
to what is in the draft standard. 

In the mean time, you could write a specialization of Foo<X>::compare
that throws an exception or invokes "assert(0)" to allow your code
to compile and link. That is, for example, if you use Foo<complex>,
you could provide the specialization
	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
which will prevent the compiler from generating a version from the template,
and will thus allow your program to compile and link.
---
Steve Clamage, stephen.clamage@eng.sun.com



[ 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. ]
Re: Template instantiation question
#1804
Author: Tony Cook
Date: Tue, 22 Aug 1995 08:18
64 lines
3083 bytes
Steve Clamage (clamage@Eng) wrote:
: In article 95Aug21100336@physics10.Berkeley.EDU, bmcphers@alias.com (Brent McPherson) writes:
: >
: >I have seen template classes that define methods that will only *work*
: >if the instantiation type provides certain methods/functionality.
: >
: >ie.
: >
: >  template<class T>
: >  class Foo {
: >  public:
: >     Foo (const T &t) : myT(T) {}
: >     // etc...
: >     int compare (const T &otherT) 
: >     { 
: >       return (myT < otherT ? -1 : myT > otherT ? 1 : 0);
: >     }
: >     // etc...
: >  };
: >
: >In this example the "compare" method relies on the object of type T
: >having comparison operators.
: >
: >Is it legal to allow Foo to be instantiated with an object that does
: >not support comparison as long as the compare method is never called
: >for that particular instantiation?

: The draft standard, 14.3.2 Point of Instantiation [temp.point], says
: the implementation shall not instantiate a class or function that does not
: require instantiation. A non-virtual function that is never called and
: never has its address taken does not require instantiation.

: In your example, if you create a variable of type Foo<X>, where X is
: some type, and never use the non-virtual compare function, that
: function, Foo<X>::compare, should not be instantiated.

: Details of template definition and instantiation have been modified or
: clarified recently, and it will take a while for compilers to catch up
: to what is in the draft standard. 

: In the mean time, you could write a specialization of Foo<X>::compare
: that throws an exception or invokes "assert(0)" to allow your code
: to compile and link. That is, for example, if you use Foo<complex>,
: you could provide the specialization
: 	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
: which will prevent the compiler from generating a version from the template,
: and will thus allow your program to compile and link.

Can we instead _declare_ the specialization and not define it:

    extern int Foo<complex>::compare(const complex &);

So that we see an error at link time rather than run-time?

This may also need specialisations for any other function that call
compare - but these may be desirable anyway.

-- 
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com
---
[ 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. ]
Re: Template instantiation question
#1814
Author: Steve Clamage
Date: Tue, 22 Aug 1995 18:22
30 lines
1924 bytes
tony@online.tmx.com.au (Tony Cook) writes:

>Steve Clamage (clamage@Eng) wrote:

>: In the mean time, you could write a specialization of Foo<X>::compare
>: that throws an exception or invokes "assert(0)" to allow your code
>: to compile and link. That is, for example, if you use Foo<complex>,
>: you could provide the specialization
>: 	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
>: which will prevent the compiler from generating a version from the template,
>: and will thus allow your program to compile and link.

>Can we instead _declare_ the specialization and not define it:

>    extern int Foo<complex>::compare(const complex &);

>So that we see an error at link time rather than run-time?

No. The declaration does not prevent instantiation if any use is made
of the function. That is, the declaration tells the compiler that
particular compare function is supposed to exist. If it is needed
but not found at link time, the system will generate it from the
template definition.

--
Steve Clamage, stephen.clamage@eng.sun.com

[ 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. ]
Re: Template instantiation question
#1826
Author: Lars Farm
Date: Wed, 23 Aug 1995 15:25
24 lines
1531 bytes
In article <41b09t$ltj@engnews2.Eng.Sun.COM>,
clamage@Eng (Steve Clamage) wrote:

>In the mean time, you could write a specialization of Foo<X>::compare
>that throws an exception or invokes "assert(0)" to allow your code
>to compile and link. That is, for example, if you use Foo<complex>,
>you could provide the specialization
>	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
>which will prevent the compiler from generating a version from the template,
>and will thus allow your program to compile and link.

Can you specialize just that one function for complex or do you have to
specialize the whole class Foo<complex> with all its members to change the
implementation of Foo<complex>::compare?

  - lars


--
lars.farm@nts.mh.se

[ 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. ]
Re: Template instantiation question
#1852
Author: Fergus Henderson
Date: Sun, 27 Aug 1995 19:10
54 lines
2797 bytes
clamage@Eng (Steve Clamage) writes:

>tony@online.tmx.com.au (Tony Cook) writes:
>
>>Steve Clamage (clamage@Eng) wrote:
>
>>: In the mean time, you could write a specialization of Foo<X>::compare
>>: that throws an exception or invokes "assert(0)" to allow your code
>>: to compile and link. That is, for example, if you use Foo<complex>,
>>: you could provide the specialization
>>: 	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
>>: which will prevent the compiler from generating a version from the template,
>>: and will thus allow your program to compile and link.
>
>>Can we instead _declare_ the specialization and not define it:
>
>>    extern int Foo<complex>::compare(const complex &);
>
>>So that we see an error at link time rather than run-time?
>
>No. The declaration does not prevent instantiation if any use is made
>of the function. That is, the declaration tells the compiler that
>particular compare function is supposed to exist. If it is needed
>but not found at link time, the system will generate it from the
>template definition.

However, if you're really keen on detecting the error at link time
rather than at runtime, it is possible to do so.
You can put the definition of Foo<complex>::compare() in a compilation
unit of its own, put that compilation unit in a library, and make sure
that the definition references some other bogus function which is
declared but not defined.

    extern int Foo<complex>::compare(const complex &) {
	extern void this_is_totally_bogus();	// declared but not defined
	this_is_totally_bogus();
	return 0;
    }

That way, if Foo<complex>::compare is referenced, the above compilation
unit will be linked in, and hence you will get an undefined reference
to `this_is_totally_bogus()'.

All things considered, however, I'm not really sure that it's worth the effort.

-- 
Fergus Henderson             |  #define x t=a[i],a[i]=a[m],a[m]=t
                             |  char a[]=" 12345678";main(m,i,j,t){for(i=m;i<
fjh@cs.mu.oz.au              |  9;x,i++)for(x,j=m;--j?(t=a[m-j]-a[m])-j&&t+j:
http://www.cs.mu.oz.au/~fjh  |  main(m+1)*0;);m-9||puts(a+1);} /* 8 queens */
---
[ 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. ]
Re: Template instantiation question
#1855
Author: Nathan Myers
Date: Mon, 28 Aug 1995 03:54
39 lines
2251 bytes
clamage@Eng (Steve Clamage) writes:

>tony@online.tmx.com.au (Tony Cook) writes:
>
>>Steve Clamage (clamage@Eng) wrote:
>
>>: In the mean time, you could write a specialization of Foo<X>::compare
>>: that throws an exception or invokes "assert(0)" to allow your code
>>: to compile and link. That is, for example, if you use Foo<complex>,
>>: you could provide the specialization
>>: 	int Foo<complex>::compare(const complex&) { assert(0); return 0; }
>>: which will prevent the compiler from generating a version from the template,
>>: and will thus allow your program to compile and link.
>
>>Can we instead _declare_ the specialization and not define it:
>
>>    extern int Foo<complex>::compare(const complex &);
>
>>So that we see an error at link time rather than run-time?
>
>No. The declaration does not prevent instantiation if any use is made
>of the function. That is, the declaration tells the compiler that
>particular compare function is supposed to exist. If it is needed
>but not found at link time, the system will generate it from the
>template definition.

(I'm sorry to jump in late.)
Sorry, I don't think this is right.   As I understand it, declaring
a specialization before every place it is used *does* prevent 
automatic instantiation.   It's a violation of ODR (not required
to be detected) if you miss declaring it first, though, in one or 
more places.

Nathan Myers
myersn@roguewave.com

[ 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. ]
Re: Template instantiation question
#1856
Author: Steve Clamage
Date: Mon, 28 Aug 1995 16:11
63 lines
3287 bytes
Distribution:
ncm@netcom.com (Nathan Myers) writes:
>clamage@Eng (Steve Clamage) writes:
>>tony@online.tmx.com.au (Tony Cook) writes:
>>>Can we instead _declare_ the specialization and not define it:
>>
>>>    extern int Foo<complex>::compare(const complex &);
>>
>>>So that we see an error at link time rather than run-time?
>>
>>No. The declaration does not prevent instantiation if any use is made
>>of the function. That is, the declaration tells the compiler that
>>particular compare function is supposed to exist. If it is needed
>>but not found at link time, the system will generate it from the
>>template definition.

>(I'm sorry to jump in late.)
>Sorry, I don't think this is right.   As I understand it, declaring
>a specialization before every place it is used *does* prevent 
>automatic instantiation.   It's a violation of ODR (not required
>to be detected) if you miss declaring it first, though, in one or 
>more places.

It seems I had two similar things confused. Thanks for the correction.

According to the 28 April draft, if you declare a NON-template
function that matches something that could be generated from the
function template, it does not prevent the generation of the
template instantiation. Example from the draft:
	template<class T> T max(T a, T b) { return a > b ? a : b; }
	int max(int, int);
The declaration does not prevent generation of max from the template
for type int, which is what I was originally thinking of. The
declaration allows you to write
	char c; int i;
	...
	max(c, i);
and get the effect of
	max(int(c), i);
via ordinary overload resolution. Without the declaration, you could
not compare an char with an int without an explicit cast.  In this
case you must not define the function max(int,int) because that
function will be generated from the template.

But if you declare an explicit template specialization
	int max<int>(int, int);
that DOES prevent the specialization from being generated
automatically. The declaration is in effect a promise that you
will supply a specialization. As Nathan says, you must be careful
to provide this declaration every place the specialization is
needed to prevent the compiler from generating it.

So the answer to the original question is "Yes, that should work".
Technically, the program is ill-formed if the program calls an
undefined function, but realistically the program will just
fail to link -- which is what was wanted.
--
Steve Clamage, stephen.clamage@eng.sun.com

---
[ 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. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads