Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
August 06, 2013 apply function to parameters | ||||
---|---|---|---|---|
| ||||
In C++11 we can write: template<class... Args> void somefunc(Args... args { ... } template<class T> T process(T p) { ... } template <class... Args> void foo(Args... args) { somefunc(process(args)...); } Is there a simple way to do this in D? |
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | In other words, I need something like this: foo(magicTemplate!(f, a1, a2, a3...)) === foo(f(a1), f(a2), f(a3)...) |
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Jack Applegame:
> Is there a simple way to do this in D?
somefunc(process(args));
Bye,
bearophile
|
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Jack Applegame:
> In other words, I need something like this:
>
> foo(magicTemplate!(f, a1, a2, a3...)) === foo(f(a1), f(a2), f(a3)...)
Sorry, your second post was not yet present and I misunderstood your question.
Take a look at std.typetuple.staticMap
Bye,
bearophile
|
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
> Take a look at std.typetuple.staticMap
staticMap works with types, and I don't know how it can help.
|
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
> On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
>> Take a look at std.typetuple.staticMap
> staticMap works with types, and I don't know how it can help.
Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
|
August 06, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Tuesday, 6 August 2013 at 16:03:07 UTC, Dicebot wrote:
> On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
>> On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
>>> Take a look at std.typetuple.staticMap
>> staticMap works with types, and I don't know how it can help.
>
> Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
Yes. Types, literals and aliases. But this doesn't help.
I wrote very ugly, but working solution. I don't like it, but I can't invent something better. :(
auto apply(alias p, alias f, Args...)(Args args) {
auto impl(uint num, Head, Tail...)(Head head, Tail tail) {
static if(num == 0) return p(head, tail);
else return impl!(num - 1)(tail, f(head));
}
return impl!(args.length)(args);
}
apply!(fun1, fun2)(arg1, arg2, ...) === fun1(fun2(arg1), fun2(arg2), ...)
offtop: Dicebot, do you speak russian?
|
August 10, 2013 Re: apply function to parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 08/06/13 18:03, Dicebot wrote:
> On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
>> On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
>>> Take a look at std.typetuple.staticMap
>> staticMap works with types, and I don't know how it can help.
>
> Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
The problem is more that staticMap requires a *template*, not a function. Another one is that doing it like that (ie storing the intermediate results in a tuple or struct) creates unnecessary copies - which isn't really an issue for small PODs, because the compiler optimizes most of the overhead away, but can have a significant cost when handling types w/ nontrivial cpctors etc.
Anyway, there are several ways to do this in D. One example:
void foo(Args...)(Args args) {
mixin(evalExpMap!(q{ somefunc(%...); }, q{ process(%s) }, args));
// == `somefunc(process(args[0]), process(args[1]), etc);`
}
// or
void foo(Args...)(Args args) {
auto result = mixin(evalExpMap!(q{ somefunc(%...) }, q{ process(%s) }, args));
//...
}
// and the helper:
template evalExpMap(string C, string F, A...) {
enum evalExpMap = {
import std.array, std.conv;
string s, l;
static if (is(typeof(A))) alias B = typeof(A);
else alias B = A;
foreach (I, _; B) {
auto r = replace( replace(F, "%s", A[I].stringof),
"%d", to!string(I));
l ~= (I?", ":"") ~ r;
s ~= r ~ ";\n";
}
return replace(replace(C, "%...;", s), "%...", l);
}();
}
Not as simple as the C++ equivalent. But not that much more complicated and *much* more powerful.
artur
|
Copyright © 1999-2021 by the D Language Foundation