Parameterized Structs

Ali Çehreli acehreli at yahoo.com
Wed Mar 2 23:50:39 PST 2011


On 03/02/2011 11:11 PM, Peter Lundgren wrote:
 > == Quote from Ali Çehreli (acehreli at yahoo.com)'s article
 >> On 03/02/2011 08:56 PM, Peter Lundgren wrote:
 >>> Where can I go to learn about parameterized structs? I can't seem 
to find any
 >>> literature on the subject. In particular, what are you allowed to 
use as a
 >>> parameter? I would like to define a struct like so:
 >>>
 >>> struct MyStruct(T, T[] a) {
 >>>       ...
 >>> }
 >>>
 >>> but I receive the following error:
 >>>
 >>> Error: arithmetic/string type expected for value-parameter, not T[]
 >>>
 >>> Are arrays not allowed?
 >> Are you trying to parametrize by the type of the container or just
 >> trying to use an array of a specified type? (As opposed to say, a linked
 >> list of the specified type?)
 >> If the former, it's simple. And the simplest thing is to just use an
 >> array in the implementation:
 >> struct S(T)
 >> {
 >>       T[] a;
 >>       void foo(T element)
 >>       {
 >>           /* Just use like an array */
 >>           a ~= element;
 >>           a[0] = element;
 >>       }
 >> }
 >> void main()
 >> {
 >>       auto s = S!double();
 >>       s.foo(1.5);
 >> }
 >> If you want to use a different container of the specified T, then a
 >> second template parameter can be used. This one uses an array as the
 >> default one:
 >> class SomeContainer
 >> {}
 >> struct S(T, Cont = T[])
 >> {
 >>       Cont a;
 >>       void foo(T element)
 >>       {
 >>           /* This time the use must match the allowed container types */
 >>       }
 >> }
 >> void main()
 >> {
 >>       auto s = S!(double, SomeContainer)();
 >>       s.foo(1.5);
 >> }
 >> I would recommend pulling information out ;) of this page:
 >>     http://digitalmars.com/d/2.0/template.html
 >> "Template Alias Parameters" is very different after C++ and can be very
 >> powerful:
 >>     http://digitalmars.com/d/2.0/template.html#TemplateAliasParameter
 >> Ali
 >
 > I'm using this for an alternative implementation of a string, if you 
will. Where T
 > is the type of a single character and a would be the alphabet (an 
array of allowed
 > characters). The rest of the implementation of the struct would, of 
course, depend
 > upon the provided alphabet.
 >
 > I guess value parameters can't be arbitrary types. I can probably get 
by with
 > using a string for my alphabet just fine, it just seemed an arbitrary 
limitation.
 > Why accept only arrays of characters when the code will be the same 
for any type?

I think the SomeContainer example above should work then: it is not 
"arrays of characters". T[] was just the default implementation. If 
SomeContainer is templatized, then I think this is what you want:

/* A templatized container */
class SomeContainer(T)
{
     /* having container functions */

     void add(T element)
     {}

     T access(size_t index)
     {
         return T.init;
     }
}

/* This is your "alternative implementation of a string". Can use any
  * container type, the default is array of Ts */
struct S(T, Cont = T[])
{
     Cont a;

     void foo(T element)
     {
         /* here the use must match the allowed container types */
     }
}

void main()
{
     /* We are instantiating it with
      *
      *   double as the element type
      *   SomeContainer!double as the container type
      */
     auto s = S!(double, SomeContainer!double)();
     s.foo(1.5);
}

But we can make it better, because 'double' and 'SomeContainer!double' 
repeat "double". Here the alias template parameters are handy:

struct S(T, alias ContType)  // <-- alias
{
     ContType!T a;            // <-- ContType!T instead of just Cont

     void foo(T element)
     {
         /* here the use must match the allowed container types */
     }
}

The second parameter is an alias template parameter. (I had to drop the 
default value; I think we can use Array!T there, but I haven't bothered 
to test.)

Now the use is easier and less error prone, because 'double' need not be 
repeated:

     auto s = S!(double, SomeContainer)();

Ali



More information about the Digitalmars-d-learn mailing list