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