Parameterized Structs

Peter Lundgren lundgrpb at rose-hulman.edu
Thu Mar 3 00:21:18 PST 2011


== Quote from Ali Çehreli (acehreli at yahoo.com)'s article
> 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

That's closer, except I want to pass a value parameter (specifically, some compile
time instance of SomeContainer) instead of a type parameter, but that doesn't look
like it's supported.


More information about the Digitalmars-d-learn mailing list