Thread overview
Template specialization
Apr 10, 2007
Derek Parnell
Apr 10, 2007
Bill Baxter
Apr 11, 2007
Derek Parnell
Apr 11, 2007
Bill Baxter
Apr 11, 2007
Derek Parnell
Apr 11, 2007
Derek Parnell
April 10, 2007
I've coded ...

 template fill_data(T : int)
 {
    void fill_data(char[] raw_data, out T t)
    {
        t = makeInt( raw_data );
    }
 }

 template fill_data(T : float)
 {
    void fill_data(char[] raw_data, out T t)
    {
        t = toFloat( raw_data );
    }
 }

and later use it like ...


  struct Foo
  {
      float xFloat;
      int   xInt;
  }
  Foo bar;

  fill_data(str, bar.xFloat);
  . . .
  fill_data(str, bar.xInt);

but when compiled I get these errors ...

 test.d(38): template procon2.fill_data(T : int) specialization not allowed
 for deduced parameter T
 test.d(46): template procon2.fill_data(T : float) specialization not
 allowed for deduced parameter T

What is the point of specialization if the compiler can't tell the difference between data types? I expected that the point of using templates is to make generic programming simpler.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
10/04/2007 6:09:58 PM
April 10, 2007
Derek Parnell wrote:
> I've coded ...
> 
>  template fill_data(T : int)
>  {
>     void fill_data(char[] raw_data, out T t)
>     {
>         t = makeInt( raw_data );
>     }
>  }
> 
>  template fill_data(T : float)
>  {
>     void fill_data(char[] raw_data, out T t)
>     {
>         t = toFloat( raw_data );
>     }
>  }
> 
> and later use it like ...
> 
> 
>   struct Foo
>   {
>       float xFloat;
>       int   xInt;
>   }
>   Foo bar;
> 
>   fill_data(str, bar.xFloat);
>   . . .
>   fill_data(str, bar.xInt);
> 
> but when compiled I get these errors ...
> 
>  test.d(38): template procon2.fill_data(T : int) specialization not allowed
>  for deduced parameter T
>  test.d(46): template procon2.fill_data(T : float) specialization not
>  allowed for deduced parameter T
> 
> What is the point of specialization if the compiler can't tell the
> difference between data types? I expected that the point of using templates
> is to make generic programming simpler.

The way I've understood it is that specialization just doesn't work with IFTI.  You have to say:

fill_data!(float)(str, bar.xFloat);
and
fill_data!(int)(str, bar.xInt);

Consequently, I don't use specialization ever.  Use 'static if' checks inside the template if you want to have both IFTI and specialization. It doesn't look as clean for many cases, but at least it's ugly on the library side, rather than the caller side.

-bb
April 11, 2007
On Tue, 10 Apr 2007 19:51:36 +0900, Bill Baxter wrote:

> Derek Parnell wrote:
>> What is the point of specialization if the compiler can't tell the difference between data types? I expected that the point of using templates is to make generic programming simpler.
> 
> The way I've understood it is that specialization just doesn't work with
> IFTI...
> ... Use 'static if' checks
> inside the template if you want to have both IFTI and specialization.

Ok, I've tried all the reasonable ways to code this but the magic syntax to do it evades my attempts. This whole area of compile-time capabilities is very poorly documented.

Anyway, below is the code I think should work, because it says exactly what I want the compiler to know. Namely, if the type (T) used in the code is and "int" then do the 'int'-stuff, etc ...

 template fill_data(T)
 {
    void fill_data(char[] raw_data, out T t)
    {
        static if (T == int) // LINE 42
        {
            t = makeInt( raw_data );
        }
        else
        static if (T == float)
        {
            t = toFloat( raw_data );
        }
        else
        {
            fscopy(t, raw_data);
        }
    }
 }

but this gives me messages that do not make sense at all to me ...

 test2.d(42): found ')' when expecting '.' following 'int'
 test2.d(43): found '{' when expecting identifier following 'int.'
 test2.d(44): found 't' when expecting ')'
 test2.d(44): found '=' instead of statement
 test2.d(46): Declaration expected, not 'else'
 test2.d(51): Declaration expected, not 'else'
 test2.d(54): unrecognized declaration

Can someone please show me the bleeding obvious correct syntax to use.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
11/04/2007 10:48:18 AM
April 11, 2007
Derek Parnell wrote:
> On Tue, 10 Apr 2007 19:51:36 +0900, Bill Baxter wrote:
> 
>> Derek Parnell wrote:
>>> What is the point of specialization if the compiler can't tell the
>>> difference between data types? I expected that the point of using templates
>>> is to make generic programming simpler.
>> The way I've understood it is that specialization just doesn't work with IFTI...
>> ... Use 'static if' checks inside the template if you want to have both IFTI and specialization. 
> 
> Ok, I've tried all the reasonable ways to code this but the magic syntax to
> do it evades my attempts. This whole area of compile-time capabilities is
> very poorly documented.
> 
> Anyway, below is the code I think should work, because it says exactly what
> I want the compiler to know. Namely, if the type (T) used in the code is
> and "int" then do the 'int'-stuff, etc ...
> 
>  template fill_data(T)
>  {
>     void fill_data(char[] raw_data, out T t)
>     {
>         static if (T == int) // LINE 42
>         {
>             t = makeInt( raw_data );
>         }
>         else
>         static if (T == float)
>         {
>             t = toFloat( raw_data );
>         }
>         else
>         {
>             fscopy(t, raw_data);
>         }
>     }
>  } 
> 
> but this gives me messages that do not make sense at all to me ...
> 
>  test2.d(42): found ')' when expecting '.' following 'int'
>  test2.d(43): found '{' when expecting identifier following 'int.'
>  test2.d(44): found 't' when expecting ')'
>  test2.d(44): found '=' instead of statement
>  test2.d(46): Declaration expected, not 'else'
>  test2.d(51): Declaration expected, not 'else'
>  test2.d(54): unrecognized declaration
> 
> Can someone please show me the bleeding obvious correct syntax to use.
> 

You need some is's there like
    static if (is(T==int))
April 11, 2007
On Wed, 11 Apr 2007 10:24:20 +0900, Bill Baxter wrote:

> Derek Parnell wrote:
>> On Tue, 10 Apr 2007 19:51:36 +0900, Bill Baxter wrote:
>> 
>>> Derek Parnell wrote:
>>>> What is the point of specialization if the compiler can't tell the difference between data types? I expected that the point of using templates is to make generic programming simpler.
>>> The way I've understood it is that specialization just doesn't work with
>>> IFTI...
>>> ... Use 'static if' checks
>>> inside the template if you want to have both IFTI and specialization.
>> 
>> Ok, I've tried all the reasonable ways to code this but the magic syntax to do it evades my attempts. This whole area of compile-time capabilities is very poorly documented.
>> 
>> Anyway, below is the code I think should work, because it says exactly what I want the compiler to know. Namely, if the type (T) used in the code is and "int" then do the 'int'-stuff, etc ...
>> 
>>  template fill_data(T)
>>  {
>>     void fill_data(char[] raw_data, out T t)
>>     {
>>         static if (T == int) // LINE 42
>>         {
>>             t = makeInt( raw_data );
>>         }
>>         else
>>         static if (T == float)
>>         {
>>             t = toFloat( raw_data );
>>         }
>>         else
>>         {
>>             fscopy(t, raw_data);
>>         }
>>     }
>>  }
>> 
>> but this gives me messages that do not make sense at all to me ...
>> 
>>  test2.d(42): found ')' when expecting '.' following 'int'
>>  test2.d(43): found '{' when expecting identifier following 'int.'
>>  test2.d(44): found 't' when expecting ')'
>>  test2.d(44): found '=' instead of statement
>>  test2.d(46): Declaration expected, not 'else'
>>  test2.d(51): Declaration expected, not 'else'
>>  test2.d(54): unrecognized declaration
>> 
>> Can someone please show me the bleeding obvious correct syntax to use.
>> 
> 
> You need some is's there like
>      static if (is(T==int))

Thank you.

I ended up with ...

 template fill_data(T)
 {
    void fill_data(char[] raw_data, T* t)
    {
        static if (is(T == int) )
        {
            *t = makeInt( raw_data );
        }
        else
        static if (is(T == float))
        {
             *t = toFloat( raw_data );
        }
        else
        {
              fscopy(t, raw_data);
        }
    }
 }

Besides your corrected syntax, I had to change the function signature to use pointers rather than use the 'out' modifier as D gets upset when using 'out' with fixed-size arrays. I don't know why it should because doing so makes it yet another exception for writing generic code.

Also, I found out that the 'static if' only compiles if it is inside the function declaration - another dumb restriction, IMNHO. Meaning that I couldn't do the obvious thing to avoid using pointers ...

 template fill_data(T)
 {
    static if (is(T == int) )
    {
        void fill_data(char[] raw_data, out T t)
        {
            t = makeInt( raw_data );
        }
    else
    static if (is(T == float))
    {
        void fill_data(char[] raw_data, out T t)
        {
             t = toFloat( raw_data );
        }
    }
    else
    {
        void fill_data(char[] raw_data, T t)
        {
              fscopy(t, raw_data);
        }
    }
 }

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
11/04/2007 12:08:05 PM
April 11, 2007
"Derek Parnell" <derek@nomail.afraid.org> wrote in message news:1x1oqnct1uxwh$.1hnmedvjme3hd$.dlg@40tude.net...
>
> I ended up with ...
>
> template fill_data(T)
> {
>    void fill_data(char[] raw_data, T* t)
>    {
>        static if (is(T == int) )
>        {
>            *t = makeInt( raw_data );
>        }
>        else
>        static if (is(T == float))
>        {
>             *t = toFloat( raw_data );
>        }
>        else
>        {
>              fscopy(t, raw_data);
>        }
>    }
> }
>
> Besides your corrected syntax, I had to change the function signature to use pointers rather than use the 'out' modifier as D gets upset when using 'out' with fixed-size arrays. I don't know why it should because doing so makes it yet another exception for writing generic code.

Don't you hate them?  They seem like they'd be so useful, too, if they could be returned and used as out parameters.

> Also, I found out that the 'static if' only compiles if it is inside the function declaration - another dumb restriction, IMNHO. Meaning that I couldn't do the obvious thing to avoid using pointers ...
>
> template fill_data(T)
> {
>    static if (is(T == int) )
>    {
>        void fill_data(char[] raw_data, out T t)
>        {
>            t = makeInt( raw_data );
>        }
>    else
>    static if (is(T == float))
>    {
>        void fill_data(char[] raw_data, out T t)
>        {
>             t = toFloat( raw_data );
>        }
>    }
>    else
>    {
>        void fill_data(char[] raw_data, T t)
>        {
>              fscopy(t, raw_data);
>        }
>    }
> }

You're missing a closing brace on that first static if clause.  But even still, this is no longer a function template and can then no longer be called using IFTI.


April 11, 2007
On Tue, 10 Apr 2007 23:07:04 -0400, Jarrett Billingsley wrote:

> ... But even still, this is no longer a function template ...

According to Walter, but I still think it looks like a template that is defining a function <G>

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
11/04/2007 2:13:36 PM
April 11, 2007
"Derek Parnell" <derek@nomail.afraid.org> wrote in message news:9vvqf3bppd67.h9vuqy06fl5n.dlg@40tude.net...
> On Tue, 10 Apr 2007 23:07:04 -0400, Jarrett Billingsley wrote:
>
>> ... But even still, this is no longer a function template ...
>
> According to Walter, but I still think it looks like a template that is defining a function <G>
>

I guess that makes sense.  If you get really technical, the static ifs don't introduce a scope, so with any given instantiation of that template, only one symbol, a function, will be declared within it, meaning it's technically a function template..  but I guess evaluation of static ifs doesn't occur until later.