www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Variadic Template Pattern

reply FoxyBrown <Foxy Brown.IPT> writes:
Hi, I have a proposal, wondering about your opinions.

Suppose one has a template function foo that accepts a variable 
number of parameters:

auto foo(T...)();

Suppose we actually want to have some type of order and type info 
instead:

auto foo(int, string)();

but we need a "variable" number of them such as

auto foo(int, string, int, string)();

auto foo(int, string, int, string, int, string)();

ad nausea.

We could simplify it all by allowing for a sort of pattern on the 
... for variadics:

auto food((int,string)...)();


and, this, of course, expands to what was described earlier.


Now, this can be accomplished already with the single template 
method and foreach/static if testing the type, but that seems 
like it's excessively verbose.
Jul 09 2017
next sibling parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sunday, July 9, 2017 9:21:03 PM MDT FoxyBrown via Digitalmars-d wrote:
 Hi, I have a proposal, wondering about your opinions.

 Suppose one has a template function foo that accepts a variable
 number of parameters:

 auto foo(T...)();

 Suppose we actually want to have some type of order and type info
 instead:

 auto foo(int, string)();

 but we need a "variable" number of them such as

 auto foo(int, string, int, string)();

 auto foo(int, string, int, string, int, string)();

 ad nausea.

 We could simplify it all by allowing for a sort of pattern on the
 ... for variadics:

 auto food((int,string)...)();


 and, this, of course, expands to what was described earlier.


 Now, this can be accomplished already with the single template
 method and foreach/static if testing the type, but that seems
 like it's excessively verbose.
A helper template could be written to use in a template constraint which checked that that number of arguments was a power of however many arguments you gave it and that they matched those types in that order. You'd probably need another helper to create a struct or something that held the pattern, since putting one AliasSeq in front of another would just merge them (e.g. matchPattern!(int, string, Args) wouldn't work), but I'm sure that it could be done, leaving you with something like auto foo(Args...)() if(matchPattern!(Pattern!(int, string), Args)) { ... } And yes, it's a bit more verbose than your suggestion, but it's a lot less verbose and more reusable than manually checking with foreach and static assertions - and it doesn't require a language change, just enough template-foo to write the helper template. - Jonathan M Davis
Jul 09 2017
prev sibling parent Joel Nilsson <nilserikjoel96 hotmail.com> writes:
On Sunday, 9 July 2017 at 21:21:03 UTC, FoxyBrown wrote:
 *snip*
If I understand what you want to achieve correctly, this can sort of be done with tuples: void func(Tuple!(int, string)[] args...){ args[0][0] // first int args[1][0] // second int args[0][1] // first string // and so on } Of course you would have to pass tuples as the arguments, so it's fairly verbose: void func(tuple(1, "one"), tuple(2, "two"), tuple(3, "three"));
Jul 10 2017