On 03/02/2011 11:11 PM, Peter Lundgren wrote:
> == Quote from Ali Çehreli (acehr...@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

Reply via email to