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