我希望能够定义一个接受接口的函数,但可以使用提供相同功能的委托或函数来实现。例如,在C++我可以写类似:在D2中交换委托/功能和接口
typedef std::function<int (float)> toInt;
void fun(toInt dg) { ... }
struct impl1 {
int operator()(float x) { ... }
};
int impl2(float x) { ... }
,然后使用任何一种实现调用它:
fun(impl1());
fun(&impl2);
(此浮子> INT转化仅仅是一个简化的例子来说明的原则,不是我的实际功能)。
我想实现D.类似的东西我天真的尝试是这样的:
interface toInt {
int opCall(float);
}
void fun(toInt dg) { ... }
int impl2(float x) { ... }
fun(impl2);
编译器会抱怨在这最后一行,它不能隐式转换impl2到toInt类型。我可能只是添加一个有趣的重载实现,并明确地进行转换,但我想知道是否有一个更优雅和通用的方法来做到这一点,就像上面的C++示例一样。
感谢您帮助新手:)这似乎是最实际的解决方案。然而,它确实增加了从调用者的角度来看的额外间接层:你调用fun(x,f)而不是f(x),就像std :: function一样。我试图用std.curry解决这个问题! (反转参数顺序为fun()并使用别名curry!(fun,x)fun1; fun1(0.0);),但编译器不高兴:Error:“template tst.main.curry!(fun,x) .curry(T)if(is(typeof(fun(arg,T.init))))不匹配任何函数模板声明“(无法推导出模板参数)。 – Eitan 2010-09-09 00:57:49
我能够通过使用[代码]别名咖喱!(fun!impl1,x)funX; funX(4.4); [/ code]这里的问题是,在'咖喱'知道如何使用它之前,模板'有趣'需要扩展到'有趣'功能。不过,这可能是一种常见的情况,应该将其添加到stdlib中。当然,你可以通过使用[code] alias curry!(fun!(typeof(x)),x)funX来使它更通用。 [/ code],以便您不必重复整个可能复杂的x类型,以便消费它的咖啡。 – 2010-09-09 03:36:02