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