是否可以在mixin模板中为函数生成名称?像这样:
mixin template Generator(string name)
{
@property void mixin(name) pure nothrow // mixin(name) is not valid :(
{
//some cool stuff here
}
}
答案 0 :(得分:4)
我希望有人可以提出更清洁的东西,但这个应该做你想做的事情:
mixin template Generator(string name)
{
mixin("alias " ~ name ~ " = _fun;");
@property void _fun pure nothrow
{
//some cool stuff here
}
}
不幸的是,这会将_fun
注入本地命名空间,但如果您多次使用Generator
,则对_fun
的任何调用都将被拒绝为不明确的。如果您合法地在其他位置定义了名为_fun
的函数,则可能会出现问题。
虽然您正在生成多个_funs
,但通过Generator
创建的别名进行的调用并不含糊,因为它们引用了特定模板实例化范围内的_fun
:
mixin Generator!"foo";
mixin Generator!"bar";
foo(); // not ambiguous, calls Generator!"foo"._fun
bar(); // not ambiguous, calls Generator!"bar"._fun
_fun(); // ambiguous, rejected by compiler
编辑:只是想抛弃我的另一个疯狂想法:
mixin template Generator(names ...) {
@property void opDispatch(string s)() pure nothrow {
foreach(name ; names) {
static if (s == name) {
// do stuff
}
}
}
}
struct Foo {
mixin Generator!("hello", "goodbye");
}
void main() {
Foo foo;
foo.hello;
foo.goodbye;
}
这可以避免生成垃圾_fun
,但它确实要求您的类尚未定义opDispatch
。此外,它不能在同一个类中多次使用(您不能在同一范围内从不同的mixin模板重载相同的方法),您必须调用它一次并将所有名称作为args传递。但是,如果您想一次性发送所有名称并且尚未定义opDispatch
,那么这可能更为可取。
答案 1 :(得分:2)
你可以使用replace在编译时做一些字符串欺骗来隐藏可怕的连接:
mixin(replace(q{
@property void mixin(name) pure nothrow
{
//some cool stuff here
}
}, q{mixin(name)}, name));