是否可以在编译时和运行时使用函数?
我想创建一个以任意顺序获取整数和浮点数的函数,并单独求它们。
static template IsSame(T){
static template As(alias t){
enum As = is(T == typeof(t));
}
}
template staticFold(alias Func, alias B,Ts...){
static if(Ts.length == 0){
alias staticFold = B;
}
else static if(Ts.length == 1){
alias staticFold = Func!(B,Ts[0]);
}
else{
alias staticFold = staticFold!(Func,Func!(B,Ts[0]),Ts[1..$]);
}
}
template Sum(alias A, alias B){
alias Sum = AliasSeq!(A + B);
}
template SumIntFloat(Ts...){
alias IntSum = staticFold!(Sum,0,Filter!(IsSame!int.As,Ts));
alias FloatSum = staticFold!(Sum,0.0f,Filter!(IsSame!float.As,Ts));
}
哪个很好用,但它似乎只在编译时工作。如果我想在运行时调用此函数怎么办?
void SumIntFloatV2(Ts...)(Ts ts){
alias Ints = Filter!(IsSame!int.As,ts);
foreach(i;Ints){
writeln(i);
}
}
这也可以工作并打印传递给函数的所有整数。
但如果我尝试使用staticFold
,则会失败。
void SumIntFloatV3(Ts...)(Ts ts){
alias Ints = Filter!(IsSame!int.As,ts);
alias IntSum = staticFold!(Sum,0,Ints);
writeln(Intsum);
}
示例函数调用:
SumIntFloatV3!(1,1.0,2,3,2.0,3.0);
SumIntFloatV3!(1,1,2,3,1.0,2.0);
答案 0 :(得分:3)
只需写一个普通的功能。在编译时上下文中调用时,它将在编译时自动解释。
struct Answer {
int IntSum = 0;
float FloatSum = 0.0;
}
Answer SumIntFloatV4(Ts...)(Ts ts) {
Answer a;
foreach(t; ts) {
static if(is(typeof(t) == int))
a.IntSum += t;
else static if(is(typeof(t) == float))
a.FloatSum += t;
}
return a;
}
void main() {
// compile time
pragma(msg, SumIntFloatV4(1,1.0,2,3,2.0,3.0));
pragma(msg, SumIntFloatV4(1,1,2,3,1.0,2.0));
// runtime
import std.stdio;
writeln(SumIntFloatV4(1,1.0,2,3,2.0,3.0));
writeln(SumIntFloatV4(1,1,2,3,1.0,2.0));
}
答案 1 :(得分:0)
虽然我很感激答案,但他们并不是我想要的。
example.com
现在可以这样称呼它:
B fold(F,B,Ts...)(F f,B init, Ts ts){
static if(ts.length == 0){
return init;
}
else{
return fold(f,f(init,ts[0]),ts[1..$]);
}
}
Tuple!(int,float) SumintFloatV3(Ts...)(Ts ts){
int intSum = fold((int a, int b) => a + b,0,Filter!(IsSame!int.As,ts));
float floatSum = fold((float a, float b) => a + b,0.0f,Filter!(IsSame!float.As,ts));
return tuple(intSum,floatSum);
}