Thread overview | ||||||
---|---|---|---|---|---|---|
|
November 15, 2014 Recursive template | ||||
---|---|---|---|---|
| ||||
Hi - I've never designed a recursive template before, but I think that would solve my problem. What I would like is someting like this: class X(V, K...) { // I want to declare a type based on K and V such // that for X!(V, int, string, double) the resulting // declaration would be: SomeType!(int, SomeType!(string, SomeType!(double, V))) var; // or put another way: SomeType!(K[0], SomeType!(K[1], SomeType(K[2], V))) var; } Can anyone give me some ideas on how to set up the declaration? Thanks, Eric |
November 15, 2014 Re: Recursive template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | On Saturday, 15 November 2014 at 18:30:00 UTC, Eric wrote:
> Hi -
>
> I've never designed a recursive template before, but I think
> that would solve my problem. What I would like is
> someting like this:
>
> class X(V, K...)
> {
> // I want to declare a type based on K and V such
> // that for X!(V, int, string, double) the resulting
> // declaration would be:
> SomeType!(int, SomeType!(string, SomeType!(double, V))) var;
>
> // or put another way:
> SomeType!(K[0], SomeType!(K[1], SomeType(K[2], V))) var;
> }
>
> Can anyone give me some ideas on how to set up the declaration?
>
> Thanks,
>
> Eric
It's pretty straight forward:
struct SomeType(K, V) {}
template X(V, K...)
{
static if(K.length == 1)
alias X = SomeType!(K[0], V);
else static if(K.length > 1)
alias X = SomeType!(K[0], X!(V, K[1 .. $]));
else static assert(false);
}
|
November 15, 2014 Re: Recursive template | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous |
Thanks!
-Eric
On Saturday, 15 November 2014 at 18:49:32 UTC, anonymous wrote:
> On Saturday, 15 November 2014 at 18:30:00 UTC, Eric wrote:
>> Hi -
>>
>> I've never designed a recursive template before, but I think
>> that would solve my problem. What I would like is
>> someting like this:
>>
>> class X(V, K...)
>> {
>> // I want to declare a type based on K and V such
>> // that for X!(V, int, string, double) the resulting
>> // declaration would be:
>> SomeType!(int, SomeType!(string, SomeType!(double, V))) var;
>>
>> // or put another way:
>> SomeType!(K[0], SomeType!(K[1], SomeType(K[2], V))) var;
>> }
>>
>> Can anyone give me some ideas on how to set up the declaration?
>>
>> Thanks,
>>
>> Eric
>
> It's pretty straight forward:
>
> struct SomeType(K, V) {}
>
> template X(V, K...)
> {
> static if(K.length == 1)
> alias X = SomeType!(K[0], V);
> else static if(K.length > 1)
> alias X = SomeType!(K[0], X!(V, K[1 .. $]));
> else static assert(false);
> }
|
November 16, 2014 Re: Recursive template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eric | Slightly simpler: struct SomeType(K, V) {} alias X(V) = V; alias X(V, K...) = SomeType!(K[0], X!(V, K[1 .. $])); That's a recurring pattern to get used to: aliasing away to one of the parameters in a terminal and/or degenerate case. Also: that an empty tuple matches no parameter "more exactly" than a tuple parameter. I know that's not at all obvious, but it's what I've found to be the case; so when K[1 ..$] above ends up as the empty tuple (that is, when all K have been exhausted), the template for X(V) will be the "more exact match." |
Copyright © 1999-2021 by the D Language Foundation