| Thread overview | |||||
|---|---|---|---|---|---|
|
September 12, 2018 Variadic template with template arguments in pairs | ||||
|---|---|---|---|---|
| ||||
I'm trying to create a variadic template function that takes pairs of arguments. Sort of like getopt, I want to pass any number of pairs of a string and some pointer. Or any size chunk larger than one.
Something like the following, assuming the existence of a hypothetical template pairwise:
---
void doByPair(Args...)(Args args)
if (Args.length)
{
foreach (pair; args.pairwise)
{
static assert(is(typeof(pair[0]) == string));
static assert(isPointer!(pair[1]));
assert(pair[1] !is null);
string desc = pair[0];
auto value = *pair[1];
writefln("%s %s: %s", typeof(value).stringof, desc, value);
}
}
bool b1 = true;
bool b2 = false;
string s = "some string";
int i = 42;
doByPair("foo", &b1, "bar", &b2, "baz", &s, "qux", &i);
---
Should output:
bool foo: true
bool bar: false
string baz: some string
int qux: 42
What is the right way to go about doing this?
| ||||
September 12, 2018 Re: Variadic template with template arguments in pairs | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Anonymouse | On Wednesday, 12 September 2018 at 15:12:16 UTC, Anonymouse wrote:
> void doByPair(Args...)(Args args)
> if (Args.length)
> {
> foreach (pair; args.pairwise)
> {
> static assert(is(typeof(pair[0]) == string));
> static assert(isPointer!(pair[1]));
> assert(pair[1] !is null);
>
> string desc = pair[0];
> auto value = *pair[1];
> writefln("%s %s: %s", typeof(value).stringof, desc, value);
> }
> }
The easiest way is probably to iterate using indices with an increment of 2, e.g.:
static foreach(i; iota(0, args.length, 2))
{
static assert(is(typeof(args[i]) == string));
static assert(isPointer!(args[i+1]));
// etc.
}
Another alternative is to write the function recursively:
void doByPair(T, Rest...)(string desc, T* valuePtr, Rest rest)
{
writefln("%s %s: %s", T.stringof, desc, *valuePtr);
if (rest.length) doByPair(rest);
}
| |||
September 15, 2018 Re: Variadic template with template arguments in pairs | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Wednesday, 12 September 2018 at 21:33:17 UTC, Paul Backus wrote:
> Another alternative is to write the function recursively:
>
> void doByPair(T, Rest...)(string desc, T* valuePtr, Rest rest)
> {
> writefln("%s %s: %s", T.stringof, desc, *valuePtr);
> if (rest.length) doByPair(rest);
> }
Rest... is genius, I don't know why it never struck me before.
My current solution doesn't support having chunks of varying sizes (ideally it would take 2 *or* 3), but the current use case is okay with just pairs for now. I imagine I could keep the same signature and just access a third argument with rest[0] and recursing on rest[1..$].
Many thanks!
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply