www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template docs

reply Josh Stern <josh_usenet phadd.net> writes:
The "Limitations" section of the language page on templates,
http://www.digitalmars.com/d/template.html  is confusing.   In 
particular, the sentence and example "Templates cannot be used 
to add non-static members or functions to classes. For example:

*************************************************
class Foo
{
    template TBar(T)
    {
	T xx;			// Error
	int func(T) { ... }	// Error

	static T yy;				// Ok
	static int func(T t, int y) { ... } 	// Ok

}

*******************************************************************

What is the "Error" in the code above?   Are the docs just out of
date?  The following apparently equivalent code, exercising template
member functions and data, declared within the enclosing class and 
outside it, seems to compile and run fine:

********************************************************************
import std.stdio;

class OBar(T) {
  T xx;
  
  this(T v) { xx = v; }
  
  double func(T t) { return t*5; }
  
}


class BadFoo {

  class TBar(T) {
    T xx;
    
    this(T v) { xx = v; }
    
    double func(T t) { return t*5; }
    
  }



  this() { 
    d_obar = new OBar!(double)(7.69); 
    d_tbar = new TBar!(double)(8.1);
  }

  OBar!(double) d_obar;
  TBar!(double) d_tbar;

  double func(T)(T t) { return d_tbar.func(t); }
}



class Foo(T) {
  this(T t) { d_foo=t; }

  T val() { return d_foo; }

  T d_foo;
}

class Test1 {

  this(double d) { d_m = d; d_d_foo = new Foo!(double)(3.14159);  }

  double prod(T)(T t) { return t*d_d_foo.val(); }
  
  double d_m;



  Foo!(double) d_d_foo;


}


void main() {


  Test1 t1 = new Test1(3.14);

  BadFoo bf = new BadFoo;
  

  writefln(t1.prod(5));
  writefln(bf.func(5));
}

***********************************************************************
Oct 10 2006
next sibling parent reply rm <roel.mathys gmail.com> writes:
Josh Stern wrote:
 The "Limitations" section of the language page on templates,
 http://www.digitalmars.com/d/template.html  is confusing.   In 
 particular, the sentence and example "Templates cannot be used 
 to add non-static members or functions to classes. For example:
 
 *************************************************
 class Foo
 {
     template TBar(T)
     {
 	T xx;			// Error
 	int func(T) { ... }	// Error
 
 	static T yy;				// Ok
 	static int func(T t, int y) { ... } 	// Ok
 
 }
 
 *******************************************************************
 
 What is the "Error" in the code above?   Are the docs just out of
 date?  The following apparently equivalent code, exercising template
 member functions and data, declared within the enclosing class and 
 outside it, seems to compile and run fine:
 
 ********************************************************************
 import std.stdio;
 
 class OBar(T) {
   T xx;
   
   this(T v) { xx = v; }
   
   double func(T t) { return t*5; }
   
 }
 
 
 class BadFoo {
 
   class TBar(T) {
     T xx;
     
     this(T v) { xx = v; }
     
     double func(T t) { return t*5; }
     
   }
 
 
 
   this() { 
     d_obar = new OBar!(double)(7.69); 
     d_tbar = new TBar!(double)(8.1);
   }
 
   OBar!(double) d_obar;
   TBar!(double) d_tbar;
 
   double func(T)(T t) { return d_tbar.func(t); }
 }
 
 
 
 class Foo(T) {
   this(T t) { d_foo=t; }
 
   T val() { return d_foo; }
 
   T d_foo;
 }
 
 class Test1 {
 
   this(double d) { d_m = d; d_d_foo = new Foo!(double)(3.14159);  }
 
   double prod(T)(T t) { return t*d_d_foo.val(); }
   
   double d_m;
 
 
 
   Foo!(double) d_d_foo;
 
 
 }
 
 
 void main() {
 
 
   Test1 t1 = new Test1(3.14);
 
   BadFoo bf = new BadFoo;
   
 
   writefln(t1.prod(5));
   writefln(bf.func(5));
 }
 
 ***********************************************************************

in your 2 examples I see 1 big difference, in the first example you templatize (is it a word?) part of the declaration of the class. in the second example the whole class is templatized. grtz roel
Oct 11 2006
parent reply Josh Stern <josh_usenet phadd.net> writes:
On Wed, 11 Oct 2006 18:47:18 +0200, rm wrote:


 in your 2 examples I see 1 big difference,
 in the first example you templatize (is it a word?) part of the
 declaration of the class.
 in the second example the whole class is templatized.

I noticed that the original example in the docs compiled okay (with suitable foo nonsense filled in) and then played around with trying to use it in different ways. Below is an example that is just like the one in the docs (except for identifier names). It compiles and runs. I'm basically just trying to understand if the docs are just completely wrong or if there is some subtle point about limitation that I'm missing even if the description of it needs improving (see note below). ****************************************** import std.stdio; class BadFoo { template TBar(T) { T xx; // Error??? int tfunc(T t) { return t.sizeof; } // Error??? } this() { d_int = TBar!(int).tfunc(5); TBar!(int).xx = 7; } int val() { return TBar!(int).xx*d_int; } int d_int; } class Norm { int x; int y; } void main() { BadFoo bf = new BadFoo; writefln(bf.val()); writefln(BadFoo.sizeof); writefln(Norm.sizeof); } ********************************************************** Output of the above is "28\n4\n4\n" I was surprised by the 4's. Are they both correct? That seems like the size of the pointer to the class rather than the class itself, or am I missing something?
Oct 11 2006
parent rm <roel.mathys gmail.com> writes:
Josh Stern wrote:
 On Wed, 11 Oct 2006 18:47:18 +0200, rm wrote:
 
 
 in your 2 examples I see 1 big difference,
 in the first example you templatize (is it a word?) part of the
 declaration of the class.
 in the second example the whole class is templatized.

I noticed that the original example in the docs compiled okay (with suitable foo nonsense filled in) and then played around with trying to use it in different ways. Below is an example that is just like the one in the docs (except for identifier names). It compiles and runs. I'm basically just trying to understand if the docs are just completely wrong or if there is some subtle point about limitation that I'm missing even if the description of it needs improving (see note below). ****************************************** import std.stdio; class BadFoo { template TBar(T) { T xx; // Error??? int tfunc(T t) { return t.sizeof; } // Error??? } this() { d_int = TBar!(int).tfunc(5); TBar!(int).xx = 7; } int val() { return TBar!(int).xx*d_int; } int d_int; } class Norm { int x; int y; } void main() { BadFoo bf = new BadFoo; writefln(bf.val()); writefln(BadFoo.sizeof); writefln(Norm.sizeof); } ********************************************************** Output of the above is "28\n4\n4\n" I was surprised by the 4's. Are they both correct? That seems like the size of the pointer to the class rather than the class itself, or am I missing something?

yep, that's a pointer size, try this: writefln(Norm.classinfo.init.sizeof); bye, rm
Oct 11 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Josh Stern wrote:
 The "Limitations" section of the language page on templates,
 http://www.digitalmars.com/d/template.html  is confusing.   In 
 particular, the sentence and example "Templates cannot be used 
 to add non-static members or functions to classes. For example:
 
 *************************************************
 class Foo
 {
     template TBar(T)
     {
 	T xx;			// Error
 	int func(T) { ... }	// Error
 
 	static T yy;				// Ok
 	static int func(T t, int y) { ... } 	// Ok
 
 }
 
 *******************************************************************
 
 What is the "Error" in the code above?   Are the docs just out of
 date?

Yes. However, all template member functions *are* implicitly final: class C { void tf(T)( T val ) { printf( "C\n" ); } alias tf!(int) f1; void f2( int val ) { tf( val ); } } class D : C { void f1( int val ) { printf( "D\n" ); } void f2( int val ) { printf( "D\n" ); } } void main( char[][] args ) { C c = new D; c.f1( 0 ); c.f2( 0 ); } prints: C D Sean
Oct 11 2006
parent Georg Wrede <georg.wrede nospam.org> writes:
Sean Kelly wrote:
 Josh Stern wrote:
 
 The "Limitations" section of the language page on templates,
 http://www.digitalmars.com/d/template.html  is confusing.   In 
 particular, the sentence and example "Templates cannot be used to add 
 non-static members or functions to classes. For example:

 *************************************************
 class Foo
 {
     template TBar(T)
     {
     T xx;            // Error
     int func(T) { ... }    // Error

     static T yy;                // Ok
     static int func(T t, int y) { ... }     // Ok

 }

 *******************************************************************

 What is the "Error" in the code above?   Are the docs just out of
 date?

Yes. However, all template member functions *are* implicitly final: class C { void tf(T)( T val ) { printf( "C\n" ); } alias tf!(int) f1; void f2( int val ) { tf( val ); } } class D : C { void f1( int val ) { printf( "D\n" ); } void f2( int val ) { printf( "D\n" ); } } void main( char[][] args ) { C c = new D; c.f1( 0 ); c.f2( 0 ); } prints: C D

I would have hoped for an error about attempting to override a final member function.
Oct 14 2006