View mode: basic / threaded / horizontal-split · Log in · Help
March 03, 2011
Parameterized Structs
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?
March 03, 2011
Re: Parameterized Structs
On Wednesday 02 March 2011 20:56:41 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?

I've never tried anything but arithmetic types and strings for a template value 
parameter, so I don't know, but the error message would certainly imply that 
it's not allowed. Regardless, its value would have to be known at compile time.

- Jonathan M Davis
March 03, 2011
Re: Parameterized Structs
On 3/2/2011 8: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?

This compiles:

	struct MyStruct(T : T[], T a)
	{
		T A = a.dup;
	}

...but I have yet to figure out how to properly invoke it.
March 03, 2011
Re: Parameterized Structs
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
March 03, 2011
Re: Parameterized Structs
== Quote from Ali Çehreli (acehreli@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?
March 03, 2011
Re: Parameterized Structs
On 03/02/2011 11:11 PM, Peter Lundgren wrote:
> == Quote from Ali Çehreli (acehreli@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
March 03, 2011
Re: Parameterized Structs
== Quote from Ali Çehreli (acehreli@yahoo.com)'s article
> On 03/02/2011 11:11 PM, Peter Lundgren wrote:
>  > == Quote from Ali Çehreli (acehreli@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.
March 03, 2011
Re: Parameterized Structs
On 03/03/2011 12:21 AM, Peter Lundgren wrote:

>>   >>  On 03/02/2011 08:56 PM, Peter Lundgren wrote:

>>   >>>  struct MyStruct(T, T[] a) {
>>   >>>        ...
>>   >>>  }
>>   >>>
>>   >>>  but I receive the following error:
>>   >>>
>>   >>>  Error: arithmetic/string type expected for value-parameter, 
not T[]

...

> 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.

I finally get it! :)

Yes, there are limitations for template value parameters. The spec at

  http://digitalmars.com/d/2.0/template.html#TemplateValueParameter

says:

<quote>
Template value parameter types can be any type which can be statically 
initialized at compile time, and the value argument can be any 
expression which can be evaluated at compile time. This includes 
integers, floating point types, and strings.
</quote>

Ali
March 03, 2011
Re: Parameterized Structs
On Thu, 03 Mar 2011 08:36:41 -0000, Ali Çehreli <acehreli@yahoo.com> wrote:

> On 03/03/2011 12:21 AM, Peter Lundgren wrote:
>
>  >>   >>  On 03/02/2011 08:56 PM, Peter Lundgren wrote:
>
>  >>   >>>  struct MyStruct(T, T[] a) {
>  >>   >>>        ...
>  >>   >>>  }
>  >>   >>>
>  >>   >>>  but I receive the following error:
>  >>   >>>
>  >>   >>>  Error: arithmetic/string type expected for value-parameter,  
> not T[]
>
> ...
>
>  > 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.
>
> I finally get it! :)
>
> Yes, there are limitations for template value parameters. The spec at
>
>    http://digitalmars.com/d/2.0/template.html#TemplateValueParameter
>
> says:
>
> <quote>
> Template value parameter types can be any type which can be statically  
> initialized at compile time, and the value argument can be any  
> expression which can be evaluated at compile time. This includes  
> integers, floating point types, and strings.
> </quote>

So.. you could pass your alphabet in a string, then split it into  
characters internally.  For example.

R
March 03, 2011
Re: Parameterized Structs
Ali Çehreli:

> <quote>
> Template value parameter types can be any type which can be statically 
> initialized at compile time, and the value argument can be any 
> expression which can be evaluated at compile time. This includes 
> integers, floating point types, and strings.
> </quote>

I have needed arrays as template specialization arguments few times (I have used alias to solve the problem). Allowing strings but not arrays is one limitation that I don't understand.

Bye,
bearophile
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home