d有趣的版本小黑客
import std;
version(traceFuncCalls)
{
// 从中提取参数元组的假函数
void locusFunc(string file = __FILE__, size_t line = __LINE__,string func = __FUNCTION__);
// 绑定参数声明到别名
static if (is(typeof(locusFunc) Params == __parameters))
alias Locus = Params;
else
static assert(0, "非函数");
}
else
alias Locus = AliasSeq!();
// 根据是否用-version=traceFuncCalls编译
// 可选地注入默认参数
void realFunc(string someOther, int args, Locus locus) {
if (locus.length > 0)
writefln("Locus = %s %s %s", locus);
else
writeln("无位置");
}
void main() {
realFunc("", 0);
//看呀!调用者中自动跟踪位置
}
用/不用,-version=traceFuncCalls选项编译来查看效果.基本上,有了该版本,Locus注入3个默认参数到realFunc的函数调用中.当*不*使用-version编译时,Locus是空元组,并从realFunc的参数列表中删除了自己.因此无运行时成本:额外参数甚至未传递给realFunc.只有使用-version编译时,才会自动插入额外的参数.
对-profile=gc情况,这是很好解决方案:只有使用-profile=gc编译时,才注入这些额外参数到Phobos函数中(此时,更改dmd版本为预定义version=D_ProfileGC,上面版本测试可以改成它),否则不会传递额外参数,也不产生额外成本.
上述技巧不适用于模板函数,因为别名阻碍了IFTI,且未提供默认参数时无法匹配实例模板.
浙公网安备 33010602011771号