Thread overview
Template docs
Oct 11, 2006
Josh Stern
Oct 11, 2006
rm
Oct 11, 2006
Josh Stern
Oct 11, 2006
rm
Oct 11, 2006
Sean Kelly
Oct 14, 2006
Georg Wrede
October 11, 2006
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));
}

***********************************************************************
October 11, 2006
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
October 11, 2006
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
October 11, 2006
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?


October 11, 2006
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
October 14, 2006
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.