https://issues.dlang.org/show_bug.cgi?id=14210
--- Comment #3 from Ketmar Dark <ket...@ketmar.no-ip.org> --- it's ok to instantiate the same template (as the function signatures are the same). but it's not ok to merge them for CTFE. actually, i have code like this: === import std.traits : isSomeFunction; Cell opIndexAssign(DT) (DT dg, string name) if (isSomeFunction!DT) { import std.traits : ParameterTypeTuple, ParameterDefaultValueTuple, ReturnType; alias args = ParameterTypeTuple!DT; alias retType = ReturnType!DT; Cell cfn; // default args can be taken only from delegate itself, not from the type, hence this hack alias defaultArguments = ParameterDefaultValueTuple!dg; cfn new CellFnX!(DT, defaultArguments)(dg); this[name] = cfn; return cfn; } private class CellFnX(DT, Defs…) : Cell { DT dg; this (DT adg) { super(aismacro); dg = adg; } override Cell execute (Milf eng, CellCons args) { … ParameterTypeTuple!DT arguments; foreach (auto idx, ref arg; arguments) { static if (!is(Defs[idx] == void)) { arg = Defs[idx]; } else { arg = Cell.from(args.car); args = args.cdr; } } } } === this is CTFE wrapper generator, and with merging like now *each* registered delegate with the same parameter types will get the same default values. this kills the whole CTFE wrapper generation idea. --