在D2中交换委托/功能和接口

Eit*_*tan 6 delegates d interface

我希望能够定义一个接口的函数,但可以使用提供相同功能的委托或函数来实现.例如,在C++中,我可以编写如下内容:

typedef std::function<int (float)> toInt;

void fun(toInt dg) { ... }

struct impl1 {
    int operator()(float x) { ... }
};

int impl2(float x) { ... }
Run Code Online (Sandbox Code Playgroud)

然后使用任一实现调用它:

fun(impl1());
fun(&impl2);
Run Code Online (Sandbox Code Playgroud)

(这个float-> int转换只是一个简单的例子来说明原理,而不是我的实际功能).

我想在D中实现类似的东西.我天真的尝试是这样的:

interface toInt {
    int opCall(float);
}

void fun(toInt dg) { ... }

int impl2(float x) { ... }

fun(impl2);
Run Code Online (Sandbox Code Playgroud)

编译器在最后一行抱怨它不能隐式地将impl2转换为toInt类型.我可能只是添加一个重载的实现的乐趣并使转换显式,但我想知道是否有更优雅和一般的方式这样做,如上面的C++示例.

小智 5

he_the_great基本上是正确的,但是下面的小改动将使它与opCall启用的结构/类一起工作.

import std.conv;
import std.stdio;
import std.traits;

void fun ( T ) ( float value, T pred )
if ( __traits( compiles, pred( value ) ) && is( ReturnType!pred : int ) )
{
    writefln( "pred( %f ) -> %s", value, pred( value ) );
}

struct impl1 {
    int opCall ( float f ) {
        return to!int( f );
    }
}

int impl2 ( float f ) {
    return to!int( f );
}

void main () {
    impl1 x;
    fun( 1.0, x );

    fun( 2.0, &impl2 );

    fun( 3.0, ( float f ){ return to!int( f ); } );
}
Run Code Online (Sandbox Code Playgroud)