Tak, to jest możliwe
import std.stdio;
import std.traits;
void foo()
{
writeln("Do It!");
}
void times(T,N)(N n, T action) if (isCallable!T && isIntegral!N)
{
static if (ParameterTypeTuple!action.length == 1
&& isIntegral!(ParameterTypeTuple!action[0]))
foreach (i; 0 .. n)
action(i);
else
foreach (i; 0 .. n)
action();
}
void main(string[] args)
{
10.times(&foo);
10.times({writeln("Do It!");});
10.times((uint n){writeln(n + 1, " Round");});
}
wersja z argumentami wspierać:
import std.stdio;
import std.traits;
void foo()
{
writeln("Do It!");
}
struct Step {
alias n this;
size_t n;
this(size_t i)
{
n = i + 1;
}
}
struct Index {
alias n this;
size_t n;
}
void times(T,N,A...)(N n, T action, A args) if (isCallable!T && isIntegral!N)
{
alias PTTAction = ParameterTypeTuple!action;
static if (PTTAction.length >= 1)
{
alias FP = PTTAction[0];
static if (is(Index == FP) || is(Step == FP))
foreach (i; 0 .. n)
action(FP(i), args);
else
action(args);
}
else
foreach (i; 0 .. n)
action();
}
void main(string[] args)
{
10.times(&foo);
10.times({writeln("Do It!");});
10.times((Step n){writeln(n, " Step");});
10.times((Index n, string msg){writeln(n, msg);}, " Index");
stdin.readln;
}
UPDATE:
dla lepszej wydajności można użyć aliasu szablonu parametr działania:
void times(alias action,N)(N n) if (isCallable!action && isIntegral!N)
{
static if (ParameterTypeTuple!action.length == 1
&& isIntegral!(ParameterTypeTuple!action[0]))
foreach (i; 0 .. n)
action(i);
else
foreach (i; 0 .. n)
action();
}
void main(string[] args)
{
10.times!(foo);
10.times!({writeln("Do It!");});
10.times!((uint n){writeln(n + 1, " Round");});
}
Btw, drugi przykład należy użyć 'foreach' zamiast' for' i rzeczywiście można usunąć 'uint'. Konwencja użyta w D dla iteratorów pętli, których nie trzeba przywoływać w pętli, nazywa je "_". Tak więc staje się "foreach (_; 0 .. N)" – yaz
Naprawdę polecam pobranie bezpłatnego odniesienia i przeczytanie go. Wszystko to odpowiada dość wcześnie w książce. Twoje pierwsze prace. Twoja sekunda byłaby dla _ w 0..N {...}. Trzeci jest możliwy, ale nie jestem pewien, czy przedłużenie czasu jest normalne. Wiem, że jest dokładnie taki przykład w prezentacjach WWDC, Myślę, że Swobodny Swift. –