Are templates with variadic value parameters possible?

Basile B. via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jul 14 21:08:19 PDT 2016


On Friday, 15 July 2016 at 03:43:49 UTC, Devin Hill wrote:
> Hi everyone,
>
> I have a struct template which takes an integer n, and then has 
> a constructor taking that many arguments of type long, which 
> looks like:
>
> struct Struct(int n) {
>     this(long[n] nums...) { /* stuff */ }
> }
>
> This works and lets me change n for each instantiation, but I 
> wanted to make a function to construct it to gain the benefit 
> of not having to write e.g.
>
> Struct!2(1, 2);    // 2 could technically be inferred from the 
> number of arguments
> Struct!3(1, 2, 3); // similar story
>
> // instead, with a function
> makeStruct!(1, 2, 3, etc...); // ideal scenario returning 
> Struct!n for some n
>
> I tried writing this:
>
> auto makeStruct(long[] nums...)() {
>     return Struct!(nums.length)(nums);
> }
>
> but sadly it seems that the syntax is not recognized, despite 
> the fact that it can be used in the non-template parameter 
> section. I have had to settle for a non-variadic version, which 
> complicates the syntax a little bit:
>
>
> // non-variadic; negatively affects calling syntax
> auto makeStruct(long[] nums)() {
>     return Struct!(nums.length)(nums);
> }
>
> makeStruct!([1, 2, 3]); // less appealing because of the extra 
> brackets
> makeStruct![1, 2, 3];   // apparently invalid, despite no 
> obvious conflict
>
>
> This started out because I just wanted a cleaner-looking 
> constructor, so it's kind of nitpicky, but now I'm just 
> interested in whether this is possible at all. Is there any way 
> to achieve what I'm trying to do without dissecting an 
> AliasSeq? In other words, can I get a type-safe variadic value 
> template parameter without conditionals? If there's anything 
> I've explained inadequately, just ask.
>
> Thanks.

With D style variadics it works, you can build the array from the 
list and have a static array:

=====
void foo(T...)(T t)
{
     T[0][T.length] tt = [t]; // T[0] is the type
     writeln(tt); // [1,2,3]
     static assert(isStaticArray!(typeof(tt)));
}

void main(string[] args)
{
     foo(1,2,3);
}
=====

Note that you should check that the elements of T[] have all the 
same type.
It shouldn't be a big problem.


More information about the Digitalmars-d-learn mailing list