Transforming an argument list
Jean-Louis Leroy via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jun 20 13:28:59 PDT 2017
Another meta-programming question ;-)
Inside a variadic function template that takes a list of
arguments, I want to call another function and pass it the
arguments run through another function. In C++ it would look like
this:
template<typename T>
T double_int(T val) { return val; }
int double_int(int val) { return 2 * val; }
template<typename... T>
void double_ints(void F(T...), T... args) {
F(double_int(args)...);
}
void test(const char* str, int val) {
cout << str << " = " << val << "\n";
}
int main() {
double_ints(test, "1 + 2", 3); // 1 + 2 = 6
return 0;
}
I tried this in D:
void test(string name, int val)
{
writefln("%s = %d", name, val);
}
template DoubleInt(A...)
{
static if (A.length == 0)
alias DoubleInt = AliasSeq!();
else static if (is(typeof(A[0]) == int))
alias DoubleInt = AliasSeq!(2 * A[0], DoubleInt!(A[1..$]));
else
alias DoubleInt = AliasSeq!(A[0], DoubleInt!(A[1..$]));
}
void double_ints(F, A...)(F f, A args)
{
f(DoubleInt!args);
}
void main()
{
double_ints(&test, "1 + 2", 3);
}
...but ldc2 complains that "variable __args_field_1 cannot be
read at compile time". Yeah, I understand...
I also tried a solution similar to C++:
A DoubleInt(A)(A a)
if (!is(typeof(A) == int))
{
return a;
}
A DoubleInt(A)(A a)
if (is(typeof(A) == int))
{
return 2 * a;
}
void double_ints(F, A...)(F f, A args)
{
f(DoubleInt!(args));
}
...but I get: "template instance callas.double_ints!(void
function(string, int), string, int) error instantiating". The
difference with C++ is that I don't get to control the expansion
of the argument pack: "f(DoubleInt!(args))" is interpreted as
"f(DoubleInt!(args...))", not "f(DoubleInt!(args))...".
Any ideas? Thanks...
More information about the Digitalmars-d-learn
mailing list